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

Passing parent constructor arguments to nested class constructor with Ninject

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

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 具有相同的索引值。

只需更改要继承给子请求的参数,如下所示:

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

这样 ConstructorArgument 适用于 Get 调用实例化的所有对象。当然 ConstructorArgument 仅在存在具有匹配名称的构造函数参数时应用。在您的情况下,ParentClassChildClass 的参数都被命名为 index,因此它有效。

另请参阅 ConstructorArgument 构造函数 here and documentation of IParameter here

的文档

更新

在较新的 Ninject 版本中,现在有 TypeMatchingConstructorArgument which matches for a type instead of a parameter name. However, if it's really a type as ubiquituous as string it makes more sense to "enclose" the configuration value in a new type, as shown by

我遇到了类似的问题,最初采用继承的构造函数参数解决方案,直到我的一位同事指出了缺点 - 如果您(或其他人)更改了构造函数参数名称(索引),您的应用程序将会中断.

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

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; }
}