C# 在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

我认为这在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);
    }
}
公共接口类
{
内部{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
实例。是的,我同意,字典就是这样做的方法