2009-11-06 14 views
10

Soy nuevo en los contenedores de IOC y estoy comenzando con NInject.Inyección de constructor con otros argumentos de constructor, sin dependencia

¿Qué hace si quiere que su constructor tenga parámetros que no son servicios y no necesita ser instanciado por el contenedor IOC?

Por ejemplo:

public class Person 
{ 
    private readonly string _name; 
    private readonly IPersonRepository _repository; 

    public Person(string name, IPersonRepository repository) 
    { 
     _name = name; 
     _repository = repository; 
    } 

    ...... 
} 

Imagínese que nombre es un requisito de la clase persona, por lo que, para asegurarse de que una persona siempre tiene un nombre, es necesario que sea aprobado para el constructor.

¿Cómo obtendríamos una instancia de Person using NInject? El nombre debe ser transferido por cualquier parte de la aplicación que esté creando una nueva Persona, mientras que el contenedor de IOC debe pasar en el IPersonRepository.

Entiendo que, o bien el nombre o el repositorio podrían ser inyectados usando una propiedad, pero esta no sería una solución limpia, estamos perdiendo algo del poder semántico del lenguaje de programación.

Respuesta

5

La clase, como se indicó anteriormente, no sería un buen candidato para su uso con un contenedor de IOC. Aquí está mezclando preocupaciones con la entidad Person que tiene algún estado (el nombre) y realiza alguna acción (cualquiera que sea el repositorio utilizado). Si refactoriza su código para que la entidad Person se recupere o cree a través de una clase que lleva una implementación del IPersonRepository a través del constructor, entonces estará en un punto donde la inyección de dependencia tiene más sentido.

+0

OK tiene sentido - Puedo ver cómo eso funcionaría en mi código – cbp

2

Estoy respetuosamente en desacuerdo con la respuesta de Kevin McMahon anterior, y la razón es que he visto código de inyección de dependencia que hace exactamente lo que desea ... solo con un contenedor de IoC diferente. A saber, fue Castle Windsor, que es otro contenedor de Ioc. Le permitiría crear una sección en su archivo de configuración para decir qué valores debe proporcionar para el nombre (no tiene mucho sentido hacer eso para el nombre, pero si fuera una propiedad como "conexiónString", podría hacer una gran cantidad de sentido).

Así que ... no es que lo que estás tratando de hacer no sea adecuado para la inyección de dependencia en general ... es solo que Ninject no se siente cómodo con eso (o quizás Ninject también lo puede acomodar). .. No conozco todas sus funciones menos utilizadas lo suficiente como para decir).

+1

En realidad, creo que NInject puede hacer esto: por ejemplo: http://stackoverflow.com/questions/1374098/with-parameters-constructorargument-with-ninject -2-0 Pero tener que pasar los nombres de los parámetros como cadenas; no tener los argumentos del constructor visibles en Intellisense; nombre del método largo ('WithConstructorArguments') ... ¡dame un descanso! – cbp

8

Ha pasado más de un año desde que hice esta pregunta, y ahora sé más que entonces. La respuesta de Kevin es la correcta y la mejor práctica, pero a veces necesitas trabajar con clases heredadas y quieres hacer algo como lo tengo en mi pregunta. Así es como lo hago con ninject:

public class Person 
{ 
    [Inject] 
    public IPersonRepository PersonRepository { get; set; } 

    private string _name; 

    public Person(string name) 
    { 
     _name = name; 
     StaticKernelContainer.Inject(this); 
    } 
} 

Una implementación de StaticKernelContainer se puede encontrar en el proyecto extensiones Web ninject.

+1

+1 para el seguimiento – ChrisWue

+0

Pregunta relacionada y respuesta diferente aquí: http://stackoverflow.com/questions/12136926/dependency-injection-with-constructor-parameters-that-arent-interfaces#comment16245407_12136926 –

Cuestiones relacionadas