C# 在Ninject绑定中将实例映射到对象
我认为这在Ninject中是一个相对简单的场景,但我一直很难找到合适的术语来搜索它 我想做一些类似的事情:C# 在Ninject绑定中将实例映射到对象,c#,.net,ninject,ioc-container,C#,.net,Ninject,Ioc Container,我认为这在Ninject中是一个相对简单的场景,但我一直很难找到合适的术语来搜索它 我想做一些类似的事情: public interface IClass { IInner Inner { get; } } public class ConcreteClass : IClass { public ConcreteClass(IInner inner) { Inner = inner; } public IInner Inner {get
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);
}
}
公共接口类
{
内部{get;}
}
公共类:icclass
{
公共混凝土等级(内部)
{
内部=内部;
}
公共内部{get;私有集;}
}
公开课考试
{
私有绑定对象_绑定{get;set;}
私有重写BindingTest()
{
//这两条线需要一些额外的配置
Kernel.Bind().To();
Kernel.Bind().To();
_绑定=新的绑定对象(1);
IClass class1=Kernel.Get();
_绑定=新的绑定对象(2);
IClass class2=Kernel.Get();
_绑定=新的绑定对象(1);
IClass class3=Kernel.Get();
//绑定的设置应该使这些断言都通过
Assert.arame(class1.Inner,class3.Inner);
Assert.AreNotSame(class1.Inner,class2.Inner);
}
}
BindingObject
的实现并不重要,因为这只是一个玩具示例,其思想只是当且仅当传递给它们的构造函数的int
相同时,两个BindingObject
将比较相等。同样地,IInner
和ConcreteInner
的实现也无关紧要
因此,基本上,我们的想法是设置绑定,以便将
\u binding
用作键,并且每当Ninject
需要注入一个新的IInner
,如果它有一个绑定到该特定的\u binding
,它只会返回现有实例,如果没有,则创建一个新实例。是否有一些简单的内置方法可以做到这一点?如果没有,我能得到一些关于方法的指导(不一定是完整的实现)吗?看看自定义范围.InScope()
。这正是你想要的
向作用域函数提供对象的实例(您的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>();
Kernel.Bind().To();
Kernel.Bind().To().InScope(o=>{return\u binding;});
var reference1=新对象();
var reference2=新对象();
_绑定=引用1;
var class1=kernel.Get();
_绑定=引用2;
var class2=kernel.Get();
_绑定=引用1;
var class3=kernel.Get();
这里class1
和class3
将具有与IInner
相同的引用,而class2
将具有另一个引用
更多信息,请访问:
在Ninject->使用Ninject->对象范围下。看看底部。
还有一篇关于作用域的小文章:
//干杯谢谢。这要求范围对象之间的引用相等,以获得相同的
IInner
实例,而不仅仅是相等,但这已经足够了。我有点困惑,因为我看到的大部分关于InScope
(包括您链接的文章)的文档都谈到绑定是基于scope对象的生命周期的,也就是说,它是否被垃圾收集,这与上面的例子不同,我可能会制作一个字典来返回scope对象。但是你必须让对象保持活动状态,以确保返回正确的IInner
实例。是的,我同意,字典就是这样做的方法