Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
JKamue opened this issue Jun 13, 2023 · 0 comments

Comments

@JKamue
Copy link

JKamue commented Jun 13, 2023

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:

public abstract class Dokumenttyp
    : SmartEnum<Dokumenttyp>
{
    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<Dokumenttyp> Accept();
    public abstract Result<Dokumenttyp> Publish();
}
internal class Offer : Dokumenttyp
{
    internal Offer()
        : base("Offer", 1)
    {
        CanBeAccepted = true;
        CanBePublished = false;
        IsPublished = false;
    }

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

    public override Result<Dokumenttyp> Publish()
    {
        return Result.Failure<Dokumenttyp>("Please first accept the offer");
    }
}
internal class AcceptedOffer : Dokumenttyp
{
    internal AcceptedOffer()
        : base("AcceptedOffer", 2)
    {
        CanBeAccepted = false;
        CanBePublished = true;
        IsPublished = false;
    }

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

    public override Result<Dokumenttyp> Publish()
    {
        CanBePublished = false;
        IsPublished = true;
        
        return this;
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant