我认为这在Ninject中是一个相对简单的场景,但我一直难以找到合适的术语来搜索它.
我想做的事情如下:
public interface IClass
{
IInner Inner { get; }
}
public class ConcreteClass : IClass
{
public ConcreteClass(IInner inner)
{
Inner = inner;
}
public IInner Inner {get; private set;}
}
public class Test
{
private BindingObject _binding {get; set;}
private override BindingTest()
{
//These two lines need some extra configuration
Kernel.Bind<IClass>().To<ConcreteClass>();
Kernel.Bind<IInner>().To<ConcreteInner>();
_binding = new BindingObject(1);
IClass class1 = Kernel.Get<IClass>();
_binding = new BindingObject(2);
IClass class2 = Kernel.Get<IClass>();
_binding = new BindingObject(1);
IClass class3 = Kernel.Get<IClass>();
//The bindings should be set up such that these asserts both pass
Assert.AreSame(class1.Inner, class3.Inner);
Assert.AreNotSame(class1.Inner, class2.Inner);
}
}
BindingObject的实现并不重要,因为这只是一个玩具示例,这个想法只是两个BindingObjects将比较相等,当且仅当传递给它们的构造函数的int是相同的.同样,IInner和ConcreteInner的实现也无关紧要.
所以基本上这个想法是设置绑定,使得_binding用作键,每次Ninject需要注入一个新的IInner时,如果它有一个绑定到特定的_binding,它将只返回现有的实例,并创建一个新的,如果没有.是否有一些简单的内置方式来做到这一点?如果没有,我可以得到关于方法的一些指导(不一定是完整实施)吗?
最佳答案 看一下自定义范围.InScope().这正是你要找的.
您向范围func<>提供了一个对象实例(您的BindingObject).在内核中创建/检索实例时,此对象用作参考.
内核将检查IInner的实例是否存在对该对象的引用;如果是这样返回实例,否则创建新的.
例:
Kernel.Bind<IClass>().To<ConcreteClass>();
Kernel.Bind<IInner>().To<ConcreteInner>().InScope(o => { return _binding ; });
var reference1 = new object();
var reference2 = new object();
_binding = reference1;
var class1 = kernel.Get<IClass>();
_binding = reference2;
var class2 = kernel.Get<IClass>();
_binding = reference1;
var class3 = kernel.Get<IClass>();
这里class1和class3将具有相同的IInner引用,而class2将具有另一个引用.
更多信息:
在Ninject下的http://www.ninject.org/wiki.html – >使用Ninject – >对象范围.看看底部附近.
以及关于范围的一篇小文章:http://bobcravens.com/2010/03/ninject-life-cycle-management-or-scoping/
//干杯