ardalis / ardalis/SmartEnum

Loading SmartEnum from Entity Framework without specifying it as a static property

Open
#405 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
2.4k
Forks
184
PR merge metrics
No merged PRs in 30d

Description

Could you please provide assistance with a use case we are facing?
We are currently exploring ways to avoid defining all deriving classes of a smart enum as static properties, as we are concerned about the potential for creating invalid states.

Specifically, we have two types: `Offers` and `AcceptedOffers`. In order to obtain an `AcceptedOffer`, one must first accept an `Offer` using the `Accept()` method. Our objective is to ensure that creating `AcceptedOffers` through any other means is not possible.
However this does not work when using the entity framwork because that relies on having a static property available for loading.

Is it feasible to modify the functionality of `ConfigureSmartEnum()` so that it can also discover private properties? Perhaps by introducing a modifier in an overload to maintain backward compatibility?

Alternatively, do smart enums offer an option to utilize reflection and list all derived classes in the assembly?

Would you be open to accepting pull requests if we were to implement any of these ideas?

Here's an example that showcases our use case:

```c#
public abstract class Dokumenttyp
: SmartEnum
{
public static readonly Dokumenttyp Offers = new Offers();

// TODO: We want to be able to remove this static property
public static readonly Dokumenttyp AcceptedOffer = new AcceptedOffer();

protected Dokumenttyp(string name, int value)
: base(name, value)
{
}

public bool CanBeAccepted { get; protected init; }

public bool IsPublished { get; protected set; }
public bool CanBePublished { get; protected set; }

public abstract Result Accept();
public abstract Result Publish();
}

```

```c#
internal class Offer : Dokumenttyp
{
internal Offer()
: base("Offer", 1)
{
CanBeAccepted = true;
CanBePublished = false;
IsPublished = false;
}

public override Result Accept()
{
return Result
.Success(new AcceptedOffer());
}

public override Result Publish()
{
return Result.Failure("Please first accept the offer");
}
}
```

```c#
internal class AcceptedOffer : Dokumenttyp
{
internal AcceptedOffer()
: base("AcceptedOffer", 2)
{
CanBeAccepted = false;
CanBePublished = true;
IsPublished = false;
}

public override Result Accept()
{
return Result.Failure("The original offer has already been accepted");
}

public override Result Publish()
{
CanBePublished = false;
IsPublished = true;

return this;
}
}
```

Contributor guide

Open the contributing guide

Research direction

Start at ConfigureSmartEnum and trace how Entity Framework loads derived SmartEnum types through static properties. Compare the requested private-property discovery and reflection-based alternatives; done requires a decided, supported approach that preserves the example's invariant and documents the resulting behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend, databases
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.