想象一下,我有以下类和接口:
public interface IService<T> { }
public class DefaultService<T> : IService<T> { }
public class FooService : IService<Foo> { }
public class BarService : IService<Bar> { }
Run Code Online (Sandbox Code Playgroud)
我希望能够像这样从内核中获取实例:
Kernel.Get<IService<Foo>>(); // Should return FooService
Kernel.Get<IService<Bar>>(); // Should return BarService
Kernel.Get<IService<Dog>>(); // Should return DefaultService
Kernel.Get<IService<Cat>>(); // Should return DefaultService
Kernel.Get<IService<Giraffe>>(); // Should return DefaultService
Run Code Online (Sandbox Code Playgroud)
是否可以使用NInject设置绑定(可能使用约定扩展),这样我就不必手动绑定IService的每个可能的实现?
Jan*_*Jan 11
我最近一直在做类似的事情,并提出了一些更简单的问题解决方案(虽然有点弱).
什么应该足够的是将通用实现(DefaultService)绑定到通用接口,并将具体实现(FooService,BarService)绑定到具体接口.当您要求接口的具体实例时,Ninject会解决您是否定义了具体绑定.如果你这样做,它会为你提供适当的实例,否则它会落到通用绑定中.以下代码应该可以解决问题.
var kernel = new StandardKernel();
kernel.Bind(typeof(IService<>)).To(typeof(DefaultService<>));
kernel.Bind<IService<Foo>>().To<FooService>();
kernel.Bind<IService<Bar>>().To<BarService>();
Run Code Online (Sandbox Code Playgroud)
编辑:
这个概念适用于整个Ninject,因此您可以将它与Extensions.Conventions一起使用.例如,定义以下内容:
public class Foo{}
public class Bar{}
public class Dog{}
public interface IService<T>{}
public class DefaultService<T> : IService<T>{}
public class FooService : IService<Foo>{}
public class BarService : IService<Bar>{}
Run Code Online (Sandbox Code Playgroud)
使用约定来绑定服务:
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom(typeof(IService<>))
.BindSingleInterface());
Run Code Online (Sandbox Code Playgroud)
并创建和检查适当的服务:
Assert.IsInstanceOf<BarService>(kernel.Get<IService<Bar>>());
Assert.IsInstanceOf<FooService>(kernel.Get<IService<Foo>>());
Assert.IsInstanceOf<DefaultService<Dog>>(kernel.Get<IService<Dog>>());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5914 次 |
| 最近记录: |