2012-07-26 8 views
7

Tengo las siguientes clases:Ninject unión de interfaz inyectada múltiples

using System; 

interface IA { } 

class A1 : IA { } 

class A2 : IA { } 

class B 
{ 
    public B(IA a) {} 
} 

class BProvider : Provider<B> 
{ 
    IA _a; 

    public BProvider(IA a) { _a=a; } 

    protected override B CreateInstance(IContext context) { return new B(_a); } 
} 

módulo ninject Load() Código:

Bind<IA>().To<A1>(); 
Bind<IA>().To<A2>(); 
Bind<B>().ToProvider<BProvider>(); 

código principal:

kernel.GetAll<IA>(); // works fine 
kernel.GetAll<B>(); // I expect to get IEnumerable<B> with two elements, but instead of this I get an error that there are multiple bindings of IA and ninject cannot determine which to use 

Así que la pregunta es ¿Puedo hacer que la última declaración funcione como se espera o hacerlo de otra manera?

Respuesta

2

Arrojará esa excepción porque Ninject necesitará crear una instancia del objeto del tipo BProvider. Para hacerlo, tiene que completar la dependencia en IA. Pero en el momento ... hay dos enlaces en IA, ¿cuál debo elegir? ....

Puede usar un enlace condicional para decidir qué implementación debe usarse. Una forma es con NamedAttribute:

Bind<IA>().To<A1>(); 
Bind<IA>().To<A2>().Named("SecondImpl"); 
Bind<B>().ToProvider<BProvider>(); 


class BProvider : Provider<B> 
{ 
    IA _a; 

    public BProvider([Named("SecondImpl")]IA a) { _a=a; } 

    protected override B CreateInstance(IContext context) { return new B(_a); } 
} 

En este caso A1 se inyecta en forma predeterminada en la que NamedAttribute no se especifica.

o como @Remo Gloor explica en este post: Configuring Ninject

Bind<IA>().To<A1>(); 
Bind<IA>().To<A2>().WhenParentNamed("NeedSecondImpl"); 
Bind<B>().ToProvider<BProvider>().Named("NeedSecondImpl"); 

Esto es poco más limpia, porque usted no tiene que atar su código para Ninject y simplemente puede dejar que la configuración (en un lugar).

Cuestiones relacionadas