2011-08-19 14 views
5

¿Debería considerar el uso de Properties.Settings.Default dentro de una clase como una dependencia y, por lo tanto, inyectarlo?Usar la inyección de dependencia para Properties.Settings.Default?

ej .:

public class Foo 
{ 
    private _settings; 
    private bool _myBool; 

    public Foo(Settings settings) 
    { 
     this._settings = settings; 
     this._myBool = this._settings.MyBool; 
    } 
} 

.
.

o consideraría el uso de Settings como una aplicación global como una buena práctica?

ej .:

public class Foo 
{ 
    private bool _myBool; 

    public Foo() 
    { 
     this._myBool = Properties.Settings.Default.MyBool; 
    } 
} 

Respuesta

2

Es posible que desee encapsular las configuraciones en una clase y tener una interfaz para ellas. De esta manera, de dónde vienen las configuraciones se puede cambiar para cosas como pruebas de unidades. Si también está utilizando un contenedor IoC, registre la configuración con el contenedor.

Hago esto para el ConfigurationManager y WebConfigurationManager para que pueda inyectar la configuración para las pruebas. Nathan Gloyn has wrapped the adapters and interface up already in a project que puede usar si también desea hacer esto.

+0

Me gusta la idea de una interfaz, pero no estoy seguro de cómo implementarla. ¿Quiere decir que tiene una interfaz que tiene propiedades que se correlacionan directamente con las de Configuración, o usa ConfigurationManager, de la misma manera que lo hace el código al que se vincula? No se utilizó ConfigurationManager anteriormente, por lo que no estoy muy seguro de qué hacer aquí. Otro empujón en la dirección correcta sería apreciado. :) – Andy

+0

El 'IConfigurationManager' era solo un ejemplo de dónde pueden estar las configuraciones externas en una aplicación y desea que el contenedor las manipule e inyecte en las clases. Para su clase 'Settings', me inclinaría a crear una interfaz' ISettings' que mejor se adapte a los miembros públicos de 'Settings'; así que si tiene una propiedad 'ConnectionString' en' Configuración', haga de esto una propiedad en la interfaz, etc. –

+0

Gracias por aclarar, eso tiene sentido. – Andy

2

Ellos deben ser pasados ​​como una dependencia. Imagine el escenario en el que desea cambiar ese conjunto de ajustes a través de la Prueba de unidad en su ejemplo n. ° 2: para lograrlo, debe tener algún tipo de lógica de conmutación complicada en el captador de propiedades estáticas.

Muchos contenedores IoC incluso pueden proporcionar una implementación singleton cuando se inyectan clases como esa para ayudarlo.

4

yo elegiría "ninguna de las anteriores" e inyectar directamente el valor booleano:

public class Foo 
{ 
    private readonly bool _myBool; 

    public Foo(bool myBool) 
    { 
     _myBool = myBool; 
    } 
} 

Esto desacopla Foo a partir del conocimiento de cualquier infraestructura que soporta la recuperación del valor booleano. Foo no tiene ninguna razón para introducir complejidad dependiendo de un objeto de configuración, especialmente si contiene otros valores no relacionados.

+0

+1, pero tenga en cuenta que esto es mucho más difícil de configurar con el contenedor DI. Sin embargo, probablemente sea la mejor idea. – Domenic

+0

@Domenic: definitivamente vale la pena señalar que algunos contenedores DI pueden no habilitar esto tan fácilmente como otros. Yo uso Autofac, que admite expresiones lambda para registros y así puede inyectar fácilmente valores primitivos. –

+0

@Bryan: Estoy de acuerdo, pero mis fragmentos de código anteriores fueron ideados como un ejemplo demasiado simple para los propósitos de la pregunta. Sin embargo, lo que dices es correcto, así que gracias por tu respuesta. – Andy

Cuestiones relacionadas