2011-03-15 18 views
10

Las muestras que he visto hasta ahora el siguiente aspecto:Usando Ninject, ¿puedo crear una instancia desde una interfaz sin exponer mi clase concreta?

escribir el código como éste ...

public class Samurai { 
    public IWeapon Weapon { get; private set; } 
    public Samurai(IWeapon weapon) { 
    Weapon = weapon; 
    } 
} 

Y Ninject puede asignar la interfaz para el tipo concreto así ...

public class WarriorModule : NinjectModule { 
    public override void Load() { 
    Bind<IWeapon>().To<Sword>(); 
    } 
} 

Así que cuando digo var samurai = kernel.Get<Samurai>(); en mi objeto Samurai mi IWeapon es automáticamente una espada.

Eso está bien, pero ¿y si solo quiero la espada ISword sin el samurai y la espada de hormigón está marcada como interna?

Actualmente, utilizo un resolutor de dependencias caseras donde podría decir var sword = DependencyResolver.Current.Resolve<ISword>(); y me devuelve un molde de espada como ISword. Mis clases concretas están marcadas como internas, por lo que el desarrollador debe pasar por mi resolución de dependencias para crear una instancia. ¿Ninject tiene algo similar a esto?

Y una pregunta extra, decorar mis interfaces con un atributo personalizado "DefaultConcreteType" que mi resolutor de dependencias puede usar si no existe una asignación. ¿Ninject tiene algo así tampoco?

Gracias

Respuesta

13

Cuando vincula una interfaz a un tipo concreto, puede solicitar una instancia de esa interfaz y obtener el tipo concreto. En su ejemplo, usted puede hacer esto:

var sword = kernel.Get<ISword>(); 

Y esto le daría un Sword objeto concreto. También puedes hacer mucho más con el sistema vinculante. Puede incluso Bind<ISword>().ToMethod(MySwordFactory); y escribir un método para obtener Espadas en función del contexto solicitante.

Otra cosa que puede hacer es cambiar cómo funciona el enlace según el tipo en el que se está inyectando.Por ejemplo, se puede exponer a una propiedad de una clase personalizada de este modo:

public class MyClass { 
    [Inject] 
    public ISword Sword { get; set; } 
} 

Y entonces se podría unirse a una aplicación ISword específico basado en la MiClase:

opciones
Bind<ISword>().To<Sword>().WhenInjectedInto<MyClass>(); 

Hay muchos mas , pero esto debería darte una descripción general aproximada.

0

Yo recomiendo usar una fábrica abstracta que puede crear ISword s. Esto tiene una ventaja sobre DependencyResolver en que los tipos que puede crear están limitados (a ser ISword).

Sus fábricas abstractas deberán ser públicas, al igual que su DependencyResolver.

0

Esto no responde directamente a su pregunta, pero sé que con Unity, puede hacerlo utilizando los archivos de configuración en lugar de cablear sus dependencias en el código. Ninject lamentablemente no tiene soporte para archivos de configuración.

Su alternativa a esto, es el uso de las sobrecargas no genéricas:

Bind(typeof(IWeapon)).To(typeof(Sword)); 

Y entonces usted debería ser capaz de hacer algo como:

Bind(typeof(IWeapon)).To(Type.GetType("MyNamespace.MyInternalSword")) 

pero eso es una gran fugly si pregúnteme ...

Cuestiones relacionadas