2011-07-04 13 views
5

Estoy un poco confundido con el patrón de inyección de Constructor y la regla Don’t call the container; it’ll call you.Inyección de constructor: ¿a dónde llamar?

¿Alguien puede explicarme (y tal vez alguien más) cómo la aplicación real debería derivar todas las ventajas de DI usando Constructor Injection? Doy para que algunos simple y creo ejemplo común:

DomainObject 
RepositoryObject 
DaoObject 

Las relaciones es obvia (creo) - RepositoryObject necesita DaoObject, DomainObject necesita Repositorio.

Uso de la inyección de Constructor Supongo que puedo olvidarme (en la mayoría de los casos) de la palabra clave NEW, pero cuándo, dónde y cómo debería crear nuevos objetos (principalmente dominio)? Debo escribir fábricas para todas las clases? ¿Debo referirme a DI Container en esa fábrica?

Lo mejor será cuando alguien me muestre algún ejemplo de aplicación real (por favor, no Asp.Net MVC :)) o bosqueje alguna estructura de proyecto.

+2

Ver esta respuesta: http://stackoverflow.com/questions/6277771/what-is-a-composition-root-in-the-context-of-dependency-injection/6277806#6277806 –

+0

@Mark - Ok, Creo que entiendo eso, pero tengo algunos problemas con la creación del objeto de dominio. Supongamos que he creado el objeto controlador (Global.asax como raíz de la aplicación) y ahora tengo alguna acción (publicación), y tengo que crear en este momento, digamos - Libro nuevo, y el Libro necesita alguna dependencia de c (Repositorio o alguna cosa) . Entonces, ¿cómo crear ese nuevo objeto? ¿DEBO SIEMPRE proporcionar esa dependencia al objeto Controlador, aunque algunos de ellos se usan ÚNICAMENTE para crear mi objeto "Libro"? La misma situación es con los Repositorios (algunos de sus métodos crean nuevos objetos de dominio). – mgibas

+1

http://stackoverflow.com/questions/4835046/why-not-use-an-ioc-container-to-resolve-dependencies-for-entities-business-object/4836790#4836790 –

Respuesta

1

no consigo su relación de clase por lo que aquí es un ejemplo más evidente ;-):

class FooService 
{ 
    IFooRepository FooRepository { get; set; } 

    public Service(IFooRepository fooRepository) 
    { 
     this.FooRepository = fooRepository; 
    } 
} 

class Controller 
{ 
    IFooService FooService { get; set; } 
    IBarService BarService { get; set; } 

    public Controller(IFooService fooService, IBarService barService) 
    { 
     this.FooService = fooService; 
     this.BarService = barService; 
    } 
} 

Como ya se ha dicho - no hay ni new FooRepository()new FooService() código en cualquier lugar.

+0

Necesita utilizar un contenedor que tiene una integración MVC, es decir. http://code.google.com/p/autofac/wiki/Mvc3Integration –

+0

Thx, pero sé cómo usarlo en MVC para crear el controlador, pero ¿qué ocurre con el resto de los objetos (principalmente el dominio)? – mgibas

+0

El objeto DI (objetos anidados) se creará automáticamente por el contenedor DI en función de su configuración. Tienes que configurar tu contenedor DI (ya sea a través del código o algunos archivos de configuración) diciéndole qué clase instanciar para cada argumento de constructor. En mi ejemplo, le dirá al contenedor DI que cree una instancia de 'FooService' cada vez que vea un argumento de tipo' IFooService', de modo que cuando crea un controlador, sepa qué pasar como argumento. –

1

Las respuestas y el enlace de Mark Seemann son suficientes pero quiero agregar algo. Como principiante de DI (que soy) esta pregunta siempre me molesta: "Ok, no hay nada nuevo, pero ¿cuándo y cómo se llaman e inyectan mis objetos reales?". Me tomó un tiempo para entender y aplicar.

Al seguir las respuestas y los enlaces, verá eso. Debe registrar sus interfaces y clases en su archivo Global.asax de aplicaciones para la aplicación web. Por ejemplo, si está usando Ninject vaya a Nuget y descargue Ninject.Web (que es para formularios web) y aplíquelo como en este ejemplo http://azolotar.blog.com/2010/06/22/ninject-2-0-in-webforms/

Punto clave en el ejemplo.

  • Global.asax se hereda de NinjectHttpApplication (que está en Ninject.Web.dll)
  • método CreateKernel se anula aquí es donde se crea el núcleo y dice a su mapa dependecy al contenedor
  • BasePage: este es para formularios web, por lo que su interfaz en las páginas se resolverá si se derivan todas de la página base.

debo añadir esto, la aplicación BasePage es bastante fácil (aquí está el código de github) es probable que ya tiene una basepage por lo que añadir esta línea KernelContainer.Inject (this); al OnInit de su página base puede resolver el problema. Un último remanente, si va a usar algo en ascx, debe anular el OnInit de su ascx para que el contenedor pueda resolver las dependencias.

Sé que dijo sin MVC o en la web:?) Pero la lógica es la misma

  • Ajuste su mapa depenceny el inicio de la aplicación (principal de ventanas)
  • Desde su no web sin ningún URL llamando directamente a los formularios, lo llamará How to use Ninject in a Windows Forms application? como en este ejemplo.No sé si está utilizando algunos patrones MVP o MVVM pero este puede ser un punto de partida

Maldición esto suena no ayuda a responder pero de todos modos, espero que esto ayude.

Cuestiones relacionadas