私は複数の実装を持つインターフェースを持っています。これらの実装は、名前のバインディングを経由して設定されていますNinjectで名前付きバインディングを飾る方法
Bind<IService>().To<FirstService>().Named("First");
Bind<IService>().To<SecondService>().Named("Second");
Bind<IService>().To<ThirdService>().Named("Third");
はしかし、これらの各サービスは、同様に装飾する必要があります
Bind<IService>().To<FirstService>().WhenInjectedInto<FirstDecorator>();
Bind<IService>().To<FirstDecorator>().WhenInjectedInto<SecondDecorator>();
Bind<IService>().To<SecondDecorator>();
私は結合WhenParentNamed
とWhenAnyAncestorNamed
文脈があることを知っているが、彼らWhenInjectedInto
と相互排他的であるようです。デコレーションと名前付きバインディングの両方を尊重するようにNinjectを設定するにはどうすればよいですか?私はProvider
スキームが動作するように設定しましたが、カスタムプロバイダなしでNinjectでこれをネイティブに行う方法があるかどうかを見たいと思っていました。
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}");
}
}
}
私はthis見てきましたが、それは名前のバインディングを扱っていないので、該当するようではありません。
更新:
理想的には、このようなものになるだろう
kernel.Get<IService>("First");
または
[Inject, Named("First")]
public IService Service {get; set;}
:ここで私はこれらの装飾のサービスのいずれかのために呼び出すことを期待する方法であります
最後はいくつかの自動統合テストです。
アップデート2:
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");
(それは具体的な実装のバインディングの名前を尊重されていないと思われるので、重複したバインディングを訴える)アップデート3を私はこれを試してみましたが、それは動作しません。は、以下の操作を行うと、ALMOST作品:
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");
問題は、それがSecondDecorator
を構築しようとすると、2つのマッチングバインディングがあるということです。 1つは具体的な実装(「First」という名前の場合はFirstService
)、もう1つはFirstDecorator
です。私が終わった
Ninject
にプル要求として提出することができるかどうかを確認するためにことになるだろうあなたはどのようにサービスを解決すると思いますか? '(" First ")'を呼び出すことによって? –
修正。その情報で質問を更新します – cidthecoatrack