我可以使用具有强命名的Ninject ConstructorArguments吗?

sti*_*k81 8 .net refactoring naming ninject constructorargument

好吧,我不知道"强命名"是否是正确的术语,但我想做的是如下.

目前我使用ConstructorArgument,例如:

public class Ninja
{
    private readonly IWeapon _weapon;
    private readonly string _name;

    public Ninja(string name, IWeapon weapon)
    {
        _weapon = weapon;
        _name = name;
    }
    // ..more code..
}

public void SomeFunction()
{
    var kernel = new StandardKernel();
    kernel.Bind<IWeapon>().To<Sword>();
    var ninja = kernel.Get<Ninja>(new ConstructorArgument("name", "Lee"));
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我重命名参数"name"(例如使用ReSharper),ConstructorArgument将不会更新,并且在创建Ninja时我将收到运行时错误.要解决这个问题,我需要手动查找我通过ConstructorArgument指定此参数的所有位置并更新它.没有好处,即使我有很好的测试覆盖率,我注定会在某些时候失败.重命名应该是一个廉价的操作.

有没有什么方法可以引用参数 - 这样当我重命名参数时它会被更新?

Rub*_*ink 5

如果你可以分享更多你真正想要实现的东西,你会得到更好的答案.一般来说,你根本不想依赖于传递一个ConstructorArgument,如果可以帮助的话 - 它应该是将参数值用于创建你不拥有的组件的最后手段,因此可以依赖于在重构活动期间被重新命名为willy nilly.因此对于普通代码,如果您可以尝试将其保留到接口以使事情明确无误并且不依赖于更好的名称.

现在不能挖掘出一个例子,但是有一种非常常见的习俗称为静态反射.提供的ConstructorArgument可以匹配任何构造函数中该名称的任何参数,因此静态反射在这个实例中不是最合适的.

因此,最好的静态反射可能会让你实现如下:

var ninja = ninject.Get<Ninja>( ParamNamesOf(()=>new Ninja( "dummy", "dummy" )).First() );
Run Code Online (Sandbox Code Playgroud)

您将看到的典型示例是,您想要提取实例上正在访问的属性的名称.这有点不同,因为它需要处理构造函数调用表达式.

至于找到一个已经拥有它的合适的lib,为搜索者练习:D(但是我建议找一种更好的方式来表达你想要做的事情,ConstructorArgument但不管怎么说这种做法都不会优先使用.)