使用Ninjects ConstructorArgument时,您可以指定要注入特定参数的确切值。为什么这个值不能为null,或者我怎样才能使它工作?也许这不是你想做的事情,但我想在我的单元测试中使用它。例如:
public class Ninja
{
private readonly IWeapon _weapon;
public Ninja(IWeapon weapon)
{
_weapon = weapon;
}
}
public void SomeFunction()
{
var kernel = new StandardKernel();
var ninja = kernel.Get<Ninja>(new ConstructorArgument("weapon", null));
}
答案 0 :(得分:7)
查看源代码(以及通过重新定义得到的堆栈跟踪,您省略了:P)
这是因为它绑定到ConstructorArgument
ctor的不同重载而不是正常用法(即,您传递的是Value Type或非null引用类型)。
解决方法是将null转换为Object: -
var ninja = kernel.Get<Ninja>( new ConstructorArgument( "weapon", (object)null ) );
Ninject 2来源:
public class ConstructorArgument : Parameter
{
/// <summary>
/// Initializes a new instance of the <see cref="ConstructorArgument"/> class.
/// </summary>
/// <param name="name">The name of the argument to override.</param>
/// <param name="value">The value to inject into the property.</param>
public ConstructorArgument(string name, object value) : base(name, value, false) { }
/// <summary>
/// Initializes a new instance of the <see cref="ConstructorArgument"/> class.
/// </summary>
/// <param name="name">The name of the argument to override.</param>
/// <param name="valueCallback">The callback to invoke to get the value that should be injected.</param>
public ConstructorArgument(string name, Func<IContext, object> valueCallback) : base(name, valueCallback, false) { }
}
摄制:
public class ReproAndResolution
{
public interface IWeapon
{
}
public class Ninja
{
private readonly IWeapon _weapon;
public Ninja( IWeapon weapon )
{
_weapon = weapon;
}
}
[Fact]
public void TestMethod()
{
var kernel = new StandardKernel();
var ninja = kernel.Get<Ninja>( new ConstructorArgument( "weapon", (object)null ) );
}
}
课?你不要下载最新的资源并查看它。很棒的评论,干净的代码库。再次感谢@Ian Davis的提示/刺激!
答案 1 :(得分:3)
我不知道Ninject,但是AFAIK构造函数注入通常用于强制依赖,因此null在这种情况下没有多大意义。如果依赖项不是必需的,则类型应提供默认构造函数并使用属性注入。
This post提供了其他信息。
答案 2 :(得分:3)
我想在单元测试中使用它
有no need to use an IOC container for unit tests。您应该使用容器在运行时将应用程序连接在一起,仅此而已。如果这开始受到伤害,它的气味就表明你的课程已经失控(SRP违规?)
您的单元测试将在此示例中:
var ninja = new Ninja(null);
以上是合法的C#代码,并且为单元测试传递空引用是一种完全有效的单元测试区域,不需要依赖。
答案 3 :(得分:0)
这可能不受支持,因为构造函数参数也可以是值类型。