2012-02-07 7 views
8

En el pasado, utilicé swiftsuspenders que es un controlador actionscript 3 IoC. Básicamente, la primera versión de switfsuspender tenía algo similar al kernel Ninject que se llamaba inyector.Necesito más ejemplos prácticos de Ninject

Si quisiera crear un inyector de aplicaciones (digamos las asignaciones más relevantes para usar en toda la aplicación), tuve que inyectar el inyector en las clases de aplicación.

Me pregunto ahora cuál es la práctica de usar kernel.get <> entre varias clases en la aplicación. ¿Debo inyectar el núcleo en sí?

Personalmente prefiero usar kernel.inject, pero si puedo hacer kernel.inject, realmente puedo inyectar las dependencias manualmente, lo cual es probablemente mejor (kiss).

Los estuches de prueba son agradables, pero están lejos de ser cuestiones prácticas reales, así que espero que puedan ayudarme a aclarar este punto. Gracias.

Editar: Me di cuenta de que algunas personas hablan sobre "contenedor raíz", parece que es el concepto que estoy buscando. ¿Cómo debo configurar un contenedor raíz y dejar que las otras clases de aplicaciones lo sepan?

Código de ejemplo Edit2 (por favor, perdona errores, es sólo, por ejemplo, sake):

class SomeClass 
{ 
    public SomeClass() 
    { 
     Command cmd = new Command(); 

     cmd.execute(); 
    } 

} 

class SomeOtherClass:ISomeOtherClass 
{ 
public void allright() 
{ 
    //right 
} 
} 

class Command 
{ 
    ISomeOtherClass dependency; 

    void execute() 
    { 
    dependency.allright(); 
    } 

} 


Program.Main() 
{ 
    IKernel kernel = new StandardKernel(); 

    kernel.Bind<SomeClass>().ToSelf().InSingletonScope(); 
    kernel.Bind<ISomeOtherClass>().To<SomeOtherClass>(); 

    SomeClass sc = kernel.Get<SomeClass>(); 
} 

no he probado esto todavía, porque todavía estoy luchando con algunos problemas de inicialización, pero mi pregunta es, ¿cómo ¿Puede la clase de comando saber sobre SomeOtherClass? Mi hipótesis actual es inyectar el kernel en SomeClass y usar el método Inject.

Respuesta

11

En cuanto a su ejemplo, está claro que SomeClass no está construido con Inversion of Control en mente; la sugerencia es que tiene una dependencia en Command, pero el control de esa dependencia se mantiene dentro del propio SomeClass. (Command cmd = new Command();)

Para invertido el control de esa dependencia, que tendría que tener una manera de inyectar que la dependencia en SomeClass. Como Remo Gloor has indicated, la forma estándar de hacer eso con Ninject es a través del constructor.

Para ello, es posible cambiar SomeClass a algo como esto:

class SomeClass 
{ 
    private ICommand _command; 

    public SomeClass(ICommand injectedCommand) 
    { 
     _command = injectedCommand; 
     _command.execute(); 
    } 

} 

Del mismo modo que se necesitaría el comando para hacer publicidad de su dependencia:

class Command 
{ 
    private ISomeOtherClass _dependency; 

    public Command(ISomeOtherClass injectedSomeOtherClass) 
    { 
     _dependency = injectedSomeOtherClass; 
    { 

    void execute() 
    { 
     _dependency.allright(); 
    } 
} 

Entonces registraría vinculante de su comando en el kernel, tal como:

Program.Main() 
{ 
    IKernel kernel = new StandardKernel(); 

    kernel.Bind<SomeClass>().ToSelf().InSingletonScope(); 
    kernel.Bind<ICommand>().To<Command>(); 
    kernel.Bind<ISomeOtherClass>().To<SomeOtherClass>(); 

    SomeClass sc = kernel.Get<SomeClass>(); 
} 

El kernel podría caminar t la cadena de dependencia e inyectarlos a todos.

+0

Gracias por la respuesta, tiene sentido, pero si bien es correcto, simplemente establece que todas las dependencias deben conocerse de antemano. ¿Qué pasa cuando esto no es posible? (por supuesto, lo que digo tiene sentido solo si los objetos se crean dinámicamente lo que podría suceder) – sebas

+0

digamos que SomeClass debe crear un número definitivo de objetos dinámicos. Al igual que SomeClass se convierte en Level y debe crear 30 estrellas. las estrellas tienen algunas dependencias, ¿cómo puede Level inyectar esas dependencias a las estrellas usando el kernel? – sebas

+0

Esa es una buena pregunta, y usted va más allá de las simples preguntas de inyección de dependencia que pueden responderse en este formato. Este tipo de situación (creación de objetos complejos) tiende a requerir una pieza más, razón por la cual Remo mencionó Fábricas en su respuesta. Debe investigar ya sea la creación de una fábrica de construcción de estrellas e inyectarla en SomeClass, o hacer que Ninject resuelva las estrellas utilizando un método de fábrica en sí o Bind(). ToProvider(). –

5

Utilice la inyección de constructor siempre que sea posible y Factories siempre que haya una buena razón para no crear las instancias junto con el objeto que dependen de ellas.

kernel.Inject solo debe utilizarse cuando no haya cambios en la creación del objeto. P.ej. un Webform

kernel.Get debe usarse exactamente una vez en la raíz de la composición (por ejemplo, Program.Main o MVC3.DependencyResolver) para crear su aplicación.

+2

¡Hola, Remo! Gracias por la respuesta. Proporcionó información útil, pero no es lo que quería saber. Me está diciendo que Get no debería utilizarse como localizador de servicios, pero lo que pregunté fue más sobre esto: digamos que tengo una clase que necesita crear un comando en uno de sus métodos. Digamos que el comando necesita algunas dependencias inyectadas y el kernel se ha definido fuera de la clase que crea el comando. ¿Cómo debería usar el kernel para inyectar las dependencias dentro de este comando? ¿Debo primero inyectar el kernel en la clase que crea el comando? – sebas

+0

mi problema es algo similar a este http://stackoverflow.com/questions/2862698/ninject-shared-di-ioc-container pero no usaría ninguna clase estática, prefiero inyectar el kernel en este momento. – sebas

+0

Debe agregar un ejemplo de código a su pregunta de lo que quiere hacer. Todo lo demás es solo adivinar. Normalmente, las dependencias se deben pasar usando la inyección de constructor que Ninject realiza automáticamente. –

Cuestiones relacionadas