使用Ninject将父构造函数参数传递给嵌套类构造函数

时间:2015-09-23 13:29:21

标签: c# ninject

我试图让ninject使用来自父类的构造函数参数,并在实例化时将其作为参数传递给子元素。我如何进行绑定以使其正常发生?我一直在浏览这些例子,并没有找到解决方案。

public class MyModule : NinjectModule
{
    public override void Load()
    {
        Bind<ParentClass>().ToSelf();
        Bind<ChildClass>().ToSelf();
    }
}

public class ParentClass
{
    private string _index;
    private ChildClass _childClass;

    public ParentClass(string index, ChildClass childClass)
    {
        _index = index;
        _childClass = childClass;
    }
}

public class ChildClass
{
    private string _index;

    public ChildClass(string index)
    {
        _index = index;
    }

    public string Index { get; set; }
}

var kernel = new StandardKernel(new MyModule());
kernel.Get<ParentClass>(new ConstructorArgument("index", "MyIndex"));

因此,当我创建ParentClass实例时,我希望其内部的ChildClass具有相同的索引值。

2 个答案:

答案 0 :(得分:3)

只需将您的参数更改为继承到子请求,如下所示:

kernel.Get<ParentClass>(new ConstructorArgument("index", "MyIndex", true));

这样ConstructorArgument适用于Get调用实例化的所有对象。当然,ConstructorArgument仅在具有匹配名称的构造函数参数时应用。在您的情况下,indexParentClass的参数都被命名为ChildClass,因此它可以正常运行。

另请参阅ConstructorArgument构造函数here的文档以及IParameter here的文档

更新

在较新的Ninject版本中,现在TypeMatchingConstructorArgument匹配一个类型而不是参数名称。但是,如果它实际上是一种与string无关的类型,那么将配置值“封闭”在一个新类型中会更有意义,如Joseph Evenson's answer所示。

答案 1 :(得分:2)

我遇到了类似的问题,最初使用继承的构造函数参数解决方案,直到我的一位同事指出了缺点 - 如果你(或其他人)改变构造函数参数名称(索引),你的应用程序将会破坏。 / p>

使用具有继承的命名构造函数参数的替代方法是创建配置类型,为此请求上下文创建新内核并将配置类型(针对该内核)绑定到常量。你最终会得到类似的东西:

public class MyModule : NinjectModule
{
    private string _index;

    public MyModule(string index)
    {
        _index = index;
    }

    public override void Load()
    {
        Bind<ConfigurationType>().ToConstant(new ConfigurationType(_index));
        Bind<ParentClass>().ToSelf();
        Bind<ChildClass>().ToSelf();
    }  
}

public class ParentClass
{
    private string _index;
    private ChildClass _childClass;

    public ParentClass(ConfigurationType configuration, ChildClass childClass)
    {
        _index = configuration.Index;
        _childClass = childClass;
    }
}

public class ChildClass
{
    private string _index;

    public ChildClass(ConfigurationType configuration configuration)
    {
        _index = configuration.Index;
    }

    public string Index { get; set; }
}