Ich habe eine Schnittstelle, die mehrere Implementierungen hat. Diese Implementierungen werden über Namen Bindungen aufgebaut:Wie verzieren benannte Bindungen in Ninject
Bind<IService>().To<FirstService>().Named("First");
Bind<IService>().To<SecondService>().Named("Second");
Bind<IService>().To<ThirdService>().Named("Third");
jedoch jeder dieser Dienste eingerichtet werden müssen, auch:
Bind<IService>().To<FirstService>().WhenInjectedInto<FirstDecorator>();
Bind<IService>().To<FirstDecorator>().WhenInjectedInto<SecondDecorator>();
Bind<IService>().To<SecondDecorator>();
Ich weiß, dass es die WhenParentNamed
und WhenAnyAncestorNamed
kontextuellen Bindung, aber sie scheinen sich mit der WhenInjectedInto
gegenseitig zu schließen. Wie kann ich Ninject so einrichten, dass sowohl die Dekoration als auch die benannten Bindungen berücksichtigt werden? Ich habe ein Provider
Schema eingerichtet, das funktioniert, aber ich wollte sehen, ob es eine Möglichkeit gab, dies nativ in Ninject zu tun, ohne die benutzerdefinierten Anbieter.
Bind<IService>().ToProvider(new ServiceProvider("First")).Named("First");
Bind<IService>().ToProvider(new ServiceProvider("Second")).Named("Second");
Bind<IService>().ToProvider(new ServiceProvider("Third")).Named("Third");
class ServiceProvider : Provider<IService>
{
private readonly string name;
public ServiceProvider(string name)
{
this.name = name;
}
protected override CreateInstance(IContext context)
{
var service = GetService(name);
var otherDependency = context.Kernel.Get<OtherDependency>();
service = new FirstDecorator(service, otherDependency);
service = new SecondDecorator(service);
return service;
}
private IService GetService(string name, IContext context)
{
switch(name)
{
case "First": return context.Kernel.Get<FirstService>();
case "Second": return context.Kernel.Get<SecondService>();
case "Third": return context.Kernel.Get<ThirdService>();
default: throw new ArugmentException($"No binding for {name}");
}
}
}
Ich habe bei this gesucht, aber da sie nicht mit dem Namen Bindungen beschäftigen, ist es nicht anwendbar zu sein scheint.
Idealerweise wäre es so etwas wie dieses:
Bind<IService>().To<FirstService>().WhenInjectedInto<FirstDecorator>().Named("First");
Bind<IService>().To<SecondService>().WhenInjectedInto<FirstDecorator>().Named("Second");
Bind<IService>().To<ThirdService>().WhenInjectedInto<FirstDecorator>().Named("Third");
Bind<IService>().To<FirstDecorator>().WhenInjectedInto<SecondDecorator>();
Bind<IService>().To<SecondDecorator>();
aktualisieren: Hier ist, wie ich für eine dieser dekoriert Dienste aufrufen erwarten:
kernel.Get<IService>("First");
oder
[Inject, Named("First")]
public IService Service {get; set;}
Die letzte ist für einige automatisierte Integrationstests.
Update 2: Ich habe dies versucht, und es funktioniert nicht (klagt über doppelte Bindungen, vermutlich, weil es nicht die Namen auf den konkreten Umsetzung Bindungen zu ehren)
Bind<IService>().To<FirstService>().WhenInjectedInto<FirstDecorator>().Named("First");
Bind<IService>().To<SecondService>().WhenInjectedInto<FirstDecorator>().Named("Second");
Bind<IService>().To<ThirdService>().WhenInjectedInto<FirstDecorator>().Named("Third");
Bind<IService>().To<FirstDecorator>().WhenInjectedInto<SecondDecorator>().Named("First");
Bind<IService>().To<FirstDecorator>().WhenInjectedInto<SecondDecorator>().Named("Second");
Bind<IService>().To<FirstDecorator>().WhenInjectedInto<SecondDecorator>().Named("Third");
Bind<IService>().To<SecondDecorator>().Named("First");
Bind<IService>().To<SecondDecorator>().Named("Second");
Bind<IService>().To<SecondDecorator>().Named("Third");
Update 3: sie folgendermaßen vorgehen NAHEZU funktioniert:
Bind<IService>().To<FirstService>().WhenAnyAncestorNamed("First");
Bind<IService>().To<SecondService>().WhenAnyAncestorNamed("Second");
Bind<IService>().To<ThirdService>().WhenAnyAncestorNamed("Third");
Bind<IService>().To<FirstDecorator>().WhenInjectedInto<SecondDecorator>().Named("First");
Bind(typeof(IService)).To(typeof(SecondDecorator)).Named("First");
Bind(typeof(IService)).To(typeof(SecondDecorator)).Named("Second");
Bind(typeof(IService)).To(typeof(SecondDecorator)).Named("Third");
das Problem ist, dass, wenn es die SecondDecorator
zu bauen versucht, gibt es zwei passende Bindungen: eine zur konkreten Implementierung (wenn sie "First" genannt wird, dann FirstService
), und eine zu der FirstDecorator
.
Wie erwarten Sie den Service zu lösen? Durch Aufruf von 'Get ("First") '? –
Korrigieren. Ich werde die Frage mit diesen Informationen aktualisieren – cidthecoatrack