7

Problema:Crear instancia de una clase con dependencias utilizando Autofac

asumir la clase:

public class MyAwesomeClass 
{ 
    private IDependCls _dependCls; 
    public MyAwesomeClass(IDependCls dependCls) 
    { 
     _dependCls = dependCls; 
    } 

} 

Y en otro lugar que necesito para obtener una instancia de esa clase, así:

public class SomewhereElse 
{ 
    public void AwesomeMethod() 
    { 
     //... 
     // AwesomeStuff 
     //... 

     var GetErDone = new MyAwesomeClass(); // PROBLEM! No constructor with 0 arguements 
    } 
} 

La pregunta es, do I

Solución propuesta 1:

A) ¿tiene que hacer un constructor adicional que resuelva la dependencia? Por ejemplo:

public MyAwesomeClass() // new constructor 
    { 
     _dependCls = DependencyResolver.Current.GetService<IDependCls>(); 
    } 


public class SomewhereElse 
{ 
    public void AwesomeMethod() 
    { 
     var GetErDone = new MyAwesomeClass(); // IT WORKS!! 
    } 
} 

Solución propuesta 2:

B) utilizar el dispositivo de resolución dentro de AwesomeMethod justo antes de var GetErDone

public class SomewhereElse 
{ 
    public void AwesomeMethod() 
    { 
     var depCls = _dependCls = DependencyResolver.Current.GetService<IDependCls>(); 
     var GetErDone = new MyAwesomeClass(depCls); // IT WORKS!! 
    } 
} 

solución Autofac?

C) ¿Alguna otra forma de Autofac?

Buscando mejores prácticas, así como una buena solución de Autofac si es posible. Creo que la primera forma es la peor ya que las dependencias opcionales podrían generar mucho desorden.

Resumen:

¿Cómo puedo obtener una new MyAwesomeClass() cuando MyAwesomeClass tiene dependencias?

+0

¿Realmente quieres decir _optional_ cuando lo dices? Si realmente es opcional, es posible que desee examinar la inyección de propiedades. Si no es así, y su computadora está atestada debido a demasiadas dependencias, tal vez su clase esté haciendo demasiado (vea también [esta respuesta] (http://stackoverflow.com/a/2420245/1282778)). –

+0

No tengo una pregunta sobre el desorden del constructor, en lugar de crear una instancia de una clase que necesita la inyección del constructor. –

+0

Gracias por no publicar la respuesta de la solución. No como cualquier otro cuerpo tiene este problema .../s –

Respuesta

7

Tenga una mirada en el patrón Composition Root.

Tiene razón, al levantar la resolución de dependencia solo se mueve el problema a otro lugar. Sin embargo, si continúa moviéndolo hacia arriba en su gráfico de objetos, llegará al punto de entrada de su aplicación. Allí redactará su gráfico de objetos.

Compárelo con Service Locator anti-pattern (usando DependencyResolver en las clases de cliente en su caso) y verá que Composition Root es una solución superior.

+0

Gracias por la respuesta. +1 porque en realidad tiene una comprensión del concepto y gracias por su artículo. Entonces, ¿supongo que esto sucederá inevitablemente? Voy a leer más sobre este enfoque, pero creo que la raíz de la composición real tal como la llamas debería ser la declaración de la unión misma. De lo contrario, se rompen las reglas de responsabilidad individual y separación de preocupaciones. –

+0

Sí, la raíz de composición se define de forma abstracta como una "ubicación", puede dividirla en varias clases, pero es importante que estén contenidas en el mismo ensamblaje. Mark Seemann, el autor de los artículos, escribió [un gran libro] (http://www.amazon.com/Dependency-Injection-NET-Mark-Seemann/dp/1935182501) acerca de DI por cierto. –

+1

@Mihalis: ¿Alguna vez obtuvo una solución satisfactoria utilizando el patrón de raíz de composición o de otro modo?Tu código de ejemplo es fácil de seguir y me gustaría ver el código para la tercera solución: thans –

0

Si desea resolver ejemplo automáticamente a través de Autofac, sólo se puede elegir de esta

  • Inyectar en el constructor de la clase
  • Inyectar en propiedad, mediante el uso de

    var builder = new ContainerBuilder();

    builder.RegisterType<Foo>().PropertiesAutowired();

  • Uso de acceso global por DependencyResolver.Current.GetService<IFoo>();

+0

Estoy usando la inyección de constructor, pero estoy preguntando sobre el proceso real de crear una instancia de esa clase. –

+0

¿Qué quiere decir proceso de crear una instancia de esa clase? ¿En qué clase quieres crear instancias? ¿Y qué es exactamente lo que quieres hacer? Prodide más información –

+0

Consulte el segundo bloque gris. Si utilizo el código como está, me sale un problema (por supuesto). Luego, propongo 2 soluciones que no me gustan, y pido un tercero, o una confirmación de que uno de los 2 que propongo es una práctica estándar. Actualizaré la respuesta para incluir realmente mis soluciones para que pueda ver –

0

En la clase que contiene MyAwesomeMethod tomar MyAwesomeClass como una dependencia constructor. Autofac se encargará de la creación de instancias.

+0

sí, pero esto acaba de mover el problema una clase más arriba, este es el punto en el que estoy realmente. ¿Qué ocurre si quiero hacer una instancia de la clase que contiene 'MyAwesomeMethod'? –

0

En primer lugar, aparte de la inyección del constructor, también puede usar property injection y method injection. Sin embargo, la inyección de constructor es la más común y el método más rápido, por lo que sugiero mantenerlo.

Lo segundo que debe hacer es registrar su MyAwesomeClass en el contenedor de Autofac junto con su dependencia, tienen algún buen examples directamente en su página de inicio.

Y lo último - no debe crear instancias de MyAwesomeClass directamente - utilice Autofac en su lugar. Aquí está un ejemplo actualización:

public void AwesomeMethod() 
{ 
    //... 
    // AwesomeStuff 
    //... 

    var GetErDone = DependencyResolver.Current.GetService<MyAwesomeClass>(); 
} 
+0

¿creará esto una nueva instancia o servicio ya registrado? – theusguy

Cuestiones relacionadas