Impostazioni dell'applicazione tramite iniezione del costruttore o contesto ambientale

3

Sto sviluppando un'applicazione contenente una classe che carica le impostazioni dell'applicazione da un file di configurazione.

Classe impostazioni:

public sealed class MyAppSettings : IMyAppSettings
{
    private IMyAppSettings DefaultSettingsInstance;

    public MyAppSettings()
    {
        DefaultLanguage = "en";

        var config = ConfigurationManager.GetSection("MyAppSettings") as NameValueCollection;

        if (config != null)
        {
            if (!string.IsNullOrEmpty(config["DefaultLanguage"]))
                DefaultLanguage = config["DefaultLanguage"];
        }
    }

    public static IMyAppSettings Default
    {
        get
        {
            return DefaultSettingsInstance ?? (DefaultSettingsInstance = new MyAppSettings());
        }
        set
        {
            if (value == null)
                throw new ArgumentNullException("value");

            DefaultSettingsInstance = value;
        }
    }

    public string DefaultLanguage { get; private set; }

}

Classe che utilizza l'impostazione (versione 1):

public sealed class SomeClass
{
    public SomeFunction()
    {
        // Using language setting here
        if(MyAppSettings.Default.DefaultLanguage == "en")
        {
            ...
        }
    }
}

o versione 2:

public sealed class SomeClass
{
    private readonly string _defaultLanguage;

    public SomeClass(string defaultLanguage)
    {
        if(string.IsNullOrEmpty(defaultLanguage))
            throw new ArgumentNullException("defaultLanguage");

        _defaultLanguage = defaultLanguage;
    }

    public SomeFunction()
    {
        // Using language setting here
        if(_defaultLanguage == "en")
        {
            ...
        }
    }
}

Entrambe le classi e l'interfaccia si trovano nello stesso assembly.

Quale approccio è migliore per le impostazioni di un'applicazione globale, passa attraverso l'iniezione di costruzione o utilizza un contesto ambientale o qualcos'altro?

    
posta Alexanderius 08.03.2014 - 14:27
fonte

2 risposte

4

Nella tua versione 2, il requisito di una lingua predefinita è esplicito, il che penso sia una buona cosa.

Nella Versione 1, se non guardi il codice sorgente, non sarà ovvio dove prende la lingua predefinita e appare come "magico", il che non è una buona cosa.

Non esiste sicuramente una soluzione unica per la scelta tra l'iniezione / setter dell'iniezione / contesto ambientale del costruttore, ma in questo particolare esempio penso che avremo un'API più pulita e un codice più robusto con l'iniezione del costruttore.

    
risposta data 08.03.2014 - 14:44
fonte
2

Nella versione 1 sembra che tu stia usando un riferimento statico per cercare l'impostazione, che è generalmente più ingombrante da controllare nei test unitari (stai scrivendo test, giusto?) di un valore iniettato dal costruttore, come nella versione 2.

Anche con la versione 2, come dice Janos nella sua risposta, il requisito esplicito di una lingua predefinita è una buona cosa, perché i consumatori ne saranno a conoscenza al momento in cui il codice viene scritto, piuttosto che a mancarlo in fase di runtime.

    
risposta data 08.03.2014 - 15:55
fonte

Leggi altre domande sui tag