问题
When using ninject conventions to bind all implementations of several interfaces I got the following problem:
public interface IServiceA { }
public interface IServiceB { }
public class Service : IServiceA, IServiceB { }
public class FooA
{
public Foo(IEnumerable<IServiceA> a)
{
// a has 2 instances of Service
}
}
public class FooB
{
public Foo(IEnumerable<IServiceB> b)
{
// b has 2 instances of Service
}
}
// ...
kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses().InheritedFrom<IServiceA>().
BindAllInterfaces());
kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses().InheritedFrom<IServiceB>().
BindAllInterfaces());
var a = new FooA(kernel.GetAll<IServiceA>());
var b = new FooB(kernel.GetAll<IServiceB>());
How should I configure the bindings in order to get only a single instance of Service
ninjected?
回答1:
Most likly your conventions is not good if there is a component that can be in two of them. But it is impossible to tell from such a abstract scenario. You should think about that, E.g. use naming conventions:
kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses().EndingWith("Service").
BindAllInterfaces());
or introduce a base interface:
kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses().InheritedFrom<IService>().
BindAllInterfaces());
or introduce an attribute, select by namespace, .... There are many ways. An other option is to select the classes in two steps:
kernel.Bind(x => x
.FromThisAssembly().SelectAllClasses().InheritedFrom<IServiceA>()
.Join().FromThisAssembly().SelectAllClasses().InheritedFrom<IServiceB>().
BindAllInterfaces());
If the service types are configured differently you can Exclude the special case in one of the bindings:
kernel.Bind(x => x
.FromThisAssembly().SelectAllClasses().InheritedFrom<IServiceA>()
.Exclude<Service>().
BindAllInterfaces());
来源:https://stackoverflow.com/questions/19271097/service-bound-multiple-times-using-ninject-extensions-conventions