2010-11-16 12 views
18

Ja na przykład 2 interfases IInterface1 i IInterface2,Oprawa jedną klasę z kilkoma interfejsami jako singleton

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

i jedną realizację tych interfejsów ImplClass.

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

muszę mieć pewność, że aplikacja ma tylko jedną instancję ImplClass, który będzie używany jako IInterface1 i IInterface2. Używam ninject do wstrzyknięcia zależności. Więc mój qustion jest: Czy poniższy kod spełni moje wymagania?

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

Lub ten kod utworzy 2 instancje ImplClass, dla interfejsu eash?

+0

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

+0

@ Czy możesz faktycznie głosować na zamknięcie (dobry telefon BTW)? –

Odpowiedz

19

Z Ninject można to zrobić:

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

Gdy klasa Impl ma zależności, których nie możesz użyć do wstrzyknięcia, możesz to zrobić:

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

Ładne i czyste.

+0

Podoba mi się. Nie musisz konfigurować klasy jako faktycznego singletonu, ale gwarantujesz, że tylko jedna instancja zostanie dostarczona. – KeithS

+0

To nie działa podczas korzystania z ActivationContext. –

+0

-1 Nie jest dobrym ogólnym rozwiązaniem, ponieważ każda uchwała prowadzi do aktywacji, zobacz http://stackoverflow.com/questions/3043441/prevent-ninject-od-calling-initialize-multiple-times-when- binding- to-several -i –

1

Podejrzewam, że spowodowałoby to utworzenie dwóch wystąpień.

Spróbuj czy następujące konstruktu pracuje dla Ciebie:

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

z następującymi Oprawa:

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

Dobra odpowiedź, i +1, ale część IMO Zaletą szkieletu IoC jest to, że można ustawić obiekt singletonowy bez konieczności definiowania struktury klas jako singletonu (co ułatwia późniejsze zmienianie zdania lub konfigurację kontenera lub rejestrację w zakresie fabryki w innym środowisko). Co jeśli po prostu zainicjowałby klasę w klasie Binding i zarejestrował ją jako zakres pojedynczej instancji? (Nie znam dobrze możliwości Ninjecta, ale Autofac nie miałby z tym problemu). – KeithS

5

Wygląda na to, że nadal używasz programu Ninject 1.5. Havn't dokładnej składni na myśli już jednak należy similat z następującą składnią 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(); 

Albo jeszcze lepiej wykorzystać Ninject.Extensions.ContextPreservation zachować kontekst.

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

To nie działa podczas korzystania z ActivationContext. –

+0

@JeffWalkerCodeRanger Proszę wyjaśnić –

+0

Został upowszechniony, chciałby zmienić na wersję na podstawie jego duplikat http://stackoverflow.com/a/4195510/11635 (i ha te same problemy z wieloma aktywacjami) –

Powiązane problemy