2010-11-16 17 views
18

He por ejemplo 2 interfases IInterface1 y IInterface2,Encuadernación una clase a varias interfaces como Singleton

public interface IInterface1 {...} 
public interface IInterface2 {...} 

y una implementación de estas interfaces ImplClass.

public class ImplClass : IInterface1, IInterface2 {...} 

tengo que estar seguro de que la aplicación tiene sólo una instancia de ImplClass, que será utilizado como IInterface1 y IInterface2. Estoy usando ninject para la inyección de dependencia. Entonces mi pregunta es: ¿El código a continuación cumplirá con mis requisitos?

... 
Bind<IInterface1>().To<ImplClass>().Using<SingletonBehavior>(); 
Bind<IInterface2>().To<ImplClass>().Using<SingletonBehavior>(); 
... 

O este código creará 2 instancias de ImplClass, para una interfaz fácil?

+0

duplicados de http://stackoverflow.com/questions/3147996/binding-singleton-to-multiple-services-in-ninject – Pete

+0

@Pete puedes votar para cerrar (buena llamada por cierto) –

Respuesta

19

Con Ninject usted puede hacer esto:

var impl = new Impl(); 
container.Bind<IInt1>().ToMethod(c => impl); 
container.Bind<IInt2>().ToMethod(c => impl); 

Cuando la clase Impl tiene dependencias que no puede Ninject para inyectar, puede hacer esto:

container.Bind<Impl>().ToSelf().InSingletonScope(); 
container.Bind<IInt1>().ToMethod(c => c.Kernel.Get<Impl>()); 
container.Bind<IInt2>().ToMethod(c => c.Kernel.Get<Impl>()); 

Agradable y limpio.

+0

Me gusta. No tiene que configurar la clase como un singleton real, pero garantiza que solo se proporciona una instancia. – KeithS

+0

Esto no funciona cuando se usa ActivationContext. –

+0

-1 No es una buena solución general ya que cada resolución lleva a una Activación, ver http://stackoverflow.com/questions/3043441/prevent-ninject-from-calling-initialize-multiple-times-when-binding-to-several -i –

1

Sospecho que esto crearía dos instancias.

Pruebe si la construcción siguiente funciona para usted:

public class ImplClass : IInterface1, IInterface2 
{ 
    public static readonly ImplClass Instance = new ImplClass(); 
} 

Con la continuación de la unión:

Bind<IInterface1>().ToMethod(c => ImplClass.Instance); 
Bind<IInterface2>().ToMethod(c => ImplClass.Instance); 
+2

Buena respuesta, y un +1, pero parte de IMO La ventaja de un marco IoC es que puede configurar un objeto singleton sin tener que definir realmente la estructura de clase como singleton (lo que le permite cambiar de opinión más adelante o configurar un registro de contenedor o de fábrica en un servidor diferente). ambiente). ¿Qué pasa si simplemente inicializó una clase en la clase de enlace y lo registró como un ámbito de instancia única? (No conozco bien las capacidades de Ninject, pero Autofac no tendría problemas para hacerlo). – KeithS

5

Parece que todavía estás usando Ninject 1.5. Me havn't la sintaxis exacta en cuenta más, pero debería ser similat a la siguiente sintaxis 2.1:

kernel.Bind<I1>().ToMethod(ctx => ctx.Kernel.Get<Impl>()); 
kernel.Bind<I2>().ToMethod(ctx => ctx.Kernel.Get<Impl>()); 
kernel.Bind<Impl>().ToSelf().InSingletonScope(); 

O incluso mejor uso Ninject.Extensions.ContextPreservation para mantener el contexto.

kernel.Bind<Impl>().ToSelf().InSingletonScope(); 
kernel.BindInterfaceToBinding<I1, Impl>(); 
kernel.BindInterfaceToBinding<I2, Impl>(); 
+0

Esto no funciona cuando se usa ActivationContext. –

+0

@JeffWalkerCodeRanger Por favor explique –

+0

Si ha votado a favor, le gustaría cambiar a voto negativo sobre la base de que es un duplicado de http://stackoverflow.com/a/4195510/11635 (y tiene los mismos problemas de activación múltiple) –

Cuestiones relacionadas