Ninject依赖注入范围

时间:2014-02-24 23:40:48

标签: dependency-injection ninject

我正在尝试使用Ninject将依赖注入到层次结构中,我对延迟注入的范围设定有疑问。我有一个包含父母和孩子的基本层次结构。孩子被注射到父母身上,他们都注射了“纹章”属性:

public class Parent
{
    [Inject]
    public Child Child { get; set; }

    [Inject]
    public CoatOfArms CoatOfArms { get; set; }
}

public class Child
{
    [Inject]
    public CoatOfArms CoatOfArms { get; set; }
}

public class CoatOfArms
{
}

由于他们在同一个家庭,他们都应该得到相同的徽章,所以我设置我的绑定,将它们的范围扩展到父请求中的CoastOfArms:

public class FamilyModule : NinjectModule
{
    public override void Load()
    {
        Bind<Parent>().ToSelf();
        Bind<Child>().ToSelf();
        Bind<CoatOfArms>().ToSelf().InScope(ctx =>
        {
            var request = ctx.Request;
            if (typeof(Parent).IsAssignableFrom(request.Service))
                return request;
            while ((request = request.ParentRequest) != null)
                if (typeof(Parent).IsAssignableFrom(request.Service))
                    return request;
            return new object();
        });
    }
}

这一切都很好,但是假设我想稍微改变一下,以便孩子在注射父母之后注射。我删除了Child属性上的Inject属性,注入内核并使用它将子进程注入方法:

    [Inject]
    public IKernel Kernel { get; set; }

    public Child Child { get; set; }

    public void InjectChild()
    {
        this.Child = this.Kernel.Get<Child>();
    }

这会中断,因为它是一个全新的请求,并且请求树的向上移动会停止此请求。我可以手动传入CoatOfArms作为属性,但是我必须记住在尝试创建子对象的代码中的其他地方都这样做。此外,子类可能有自己的子孙,等等,所以我不得不再次在层次结构链中手动传递参数,从而失去依赖注入范围的所有好处。

有没有办法创建我的子对象,并以某种方式将请求链接到父请求,以便作用域的工作方式就好像子进程与父进程同时注入一样?

1 个答案:

答案 0 :(得分:0)

使用ninject.extensions.contextpreservation(https://github.com/ninject/ninject.extensions.contextpreservation/wiki,可用作nuget包)然后更改

public void InjectChild()
{
    this.Child = this.Kernel.Get<Child>();
}

public void InjectChild()
{
    this.Child = this.Kernel.ContextPreservingGet<Child>();
}

.ContextPreservingGet<Child>()是一个扩展名,因此可能需要识别using Some.Name.Space;

顺便说一下,您还可以将自定义范围更改为以下内容: public class FamilyModule:NinjectModule {     private const string FamilyScopeName =“FamilyScopeName”;

public override void Load()
{
    Bind<Parent>().ToSelf().DefinesNamedScope(FamilyScopeName);
    Bind<Child>().ToSelf();
    Bind<CoatOfArms>().ToSelf().InNamedScope(FamilyScopeName);
}

}

这需要:https://github.com/ninject/ninject.extensions.namedscope(也可以作为nuget包使用)

编辑:您可能还需要从IKernel更改为IResolutionRoot才能解决。