2010-11-16 13 views
18

ich zum Beispiel haben 2 interfases IInterface1 und IInterface2,Bindung eine Klasse mehrere Schnittstellen wie Singleton

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

und eine Implementierung dieser Schnittstellen ImplClass.

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

Ich muss sicher sein, dass die Anwendung nur eine Instanz von ImplClass hat, die als IInterface1 und IInterface2 verwendet werden. Ich verwende Ninject für die Abhängigkeitsinjektion. Also meine Frage ist: Wird der Code unten meine Anforderungen erfüllen?

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

Oder dieser Code erstellt 2 Instanzen von ImplClass, für EASH-Schnittstelle?

+0

Duplizieren von http://stackoverflow.com erfordert/questions/3147996/binding-singleton-zu-multiple-services-in-ninject – Pete

+0

@Pete können Sie tatsächlich abstimmen (guten Ruf BTW) –

Antwort

19

Mit Ninject können Sie dies tun:

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

Wenn die Impl Klasse hat Abhängigkeiten, die Sie nicht injizieren können, können Sie dies tun:

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

Schön und sauber.

+0

Ich mag es. Sie müssen die Klasse nicht als tatsächlichen Singleton einrichten, aber Sie garantieren, dass immer nur eine Instanz bereitgestellt wird. – KeithS

+0

Dies funktioniert nicht, wenn Sie ActivationContext verwenden. –

+0

-1 Keine gute allgemeine Lösung, da jede Auflösung zu einer Aktivierung führt, siehe http://stackoverflow.com/questions/3043441/prevent-ninject-from-calling-initialize-multiple-times-when-binding-to-several -i –

1

Ich würde vermuten, dass dies zwei Instanzen erstellen würde.

Versuchen Sie, ob das folgende Konstrukt für Sie arbeitet:

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

Mit folgenden Bindung:

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

Gute Antwort, und ein +1, aber IMO Teil Der Vorteil eines IoC-Frameworks besteht darin, dass Sie ein Singleton-Objekt einrichten können, ohne die Klassenstruktur tatsächlich als Singleton definieren zu müssen (was es Ihnen später leichter macht, Ihre Meinung zu ändern oder eine Container- oder werksseitige Registrierung in einem anderen Objekt einzurichten) Umgebung). Was, wenn er einfach eine Klasse in der Binding-Klasse initialisierte und sie als Einzelinstanzbereich registrierte? (Ich kenne die Fähigkeiten von Ninject nicht so gut, aber Autofac hätte kein Problem damit). – KeithS

5

Es scheint, dass Sie immer noch Ninject 1.5 verwenden. Ich havn't die genaue Syntax im Sinn mehr, aber es sollte auf die folgenden 2.1 Syntax similat werden:

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

Oder noch besser Ninject.Extensions.ContextPreservation verwenden, den Kontext zu halten.

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

Dies funktioniert nicht, wenn Sie ActivationContext verwenden. –

+0

@JeffWalkerCodeRanger Bitte erklären Sie –

+0

Had upvoted, würde gerne ändern, um auf Basis seiner ein Duplikat von http://stackoverflow.com/a/4195510/11635 zu downvote (und ha die gleichen mehrere Aktivierungsprobleme) –

Verwandte Themen