Enum come parte del dominio - enum + estensione o consolidamento in una classe?

0

Ho un programma in cui il dominio è incentrato sui programmi.

Come parte del dominio, ho un 'ProgramType', che è un enum formato principalmente tramite una stringa dal database ma anche tramite un po 'di logica. Al momento ho diviso tra tre file (ProgramType, DatabaseTypeAttribute e ProgramTypeExtensions).

Tuttavia, questo è davvero il modo migliore per farlo? Sembra strano suddividere questo codice in questo modo. Mi piacerebbe aggregare tutto questo in una singola classe, ma non sono sicuro di come avvicinarsi a farlo (come dovrebbe comportarsi ancora come enum) - o anche se è una buona idea.

Qual è l'approccio migliore?

public enum ProgramType
{
    [DatabaseType("DESKTOP")]
    Desktop = 1,
    [DatabaseType("WEB")]
    Web = 2,
    Unknown = 3,
    BrokenDesktop = 4
}

internal class DatabaseTypeAttribute : Attribute
{
    internal string DatabaseType { get; }

    internal DatabaseTypeAttribute(string type)
    {
        DatabaseType = type;
    }
}

public static class ProgramTypeExtensions
{
    public static string GetDatabaseType(this ProgramType programType)
    {
        var type = programType.GetType();
        var name = Enum.GetName(type, programType);
        return type.GetField(name).GetCustomAttributes(false)
            .OfType<DatabaseTypeAttribute>().SingleOrDefault()?.DatabaseType;
    }

    internal static ProgramType GetProgramType(DatabaseTypeAttribute databaseType,
        string url)
    {
        var dbType = GetValueFromDatabaseType(databaseType.DatabaseType);

        if (dbType == ProgramType.Desktop && !File.Exists(url))
        {
            return ProgramType.BrokenDesktop;
        }

        return dbType;
    }

    private static ProgramType GetValueFromDatabaseType(string databaseType)
    {
        var pgmType = Enum.GetValues(typeof(ProgramType)).Cast<ProgramType?>()
            .FirstOrDefault(pgmtype =>
                pgmtype != null && pgmtype.Value.GetDatabaseType() == databaseType);

        return pgmType ?? ProgramType.Unknown;
    }
}

Come richiesto, ecco come vengono utilizzati i metodi di estensione:

//In Repo:
var parameters = new List<DBParametre>
{
    new DBParametre(ProgramType.Web.GetDatabaseType()),
};

//In domain object:
public Program(string name, string type, string url)
{
    Name = name;
    Url = url;
    Type = ProgramTypeExtensions.GetProgramType(type, url);
}
    
posta Sarov 28.06.2018 - 18:27
fonte

1 risposta

1

Alcune cose:

Puoi nidificare le enumerazioni (è più di un hack strongmente tipizzato), anche se il codice sembra un po 'terribile: link

È possibile semplificare la logica enum utilizzando [enum] .ToString () per ottenere il nome anziché il riflesso.

L'intero punto di un enum è di avere un valore di ricerca nel db, quindi 0-5 nel db non significa nulla (al codice c #), ma nell'enumerazione sono strongmente tipizzati rendendo il codice leggibile . Memorizzare il nome enum come una stringa nel db sconfigge lo scopo imho.

Infine, se non volessi fare quanto sopra (non lo farei) puoi creare una classe chiamata "Programma" per incapsulare il tipo di programma e il tipo di database e quindi controllarne la relazione attraverso il codice.

    
risposta data 29.06.2018 - 01:05
fonte