我有以下代码:
namespace Test.Ninject.ConstructorArgumentBug
{
public class ClassA
{
private readonly IDependecy _dependecy;
public ClassA(IDependecy dependecy)
{
_dependecy = dependecy;
}
}
public interface IDependecy
{
}
public class ConcreteDependency : IDependecy
{
private readonly string _arg;
public ConcreteDependency(string arg)
{
_arg = arg;
}
}
public class Tests
{
[Test]
public void Test1()
{
var kernel = new StandardKernel();
kernel.Bind<IDependecy>()
.To<ConcreteDependency>()
.WhenInjectedInto<ClassA>()
.WithConstructorArgument(new ConstructorArgument("arg", "test"));
var classA = kernel.Get<ClassA>();
Assert.IsNotNull(classA);
}
[Test]
public void Test2()
{
var kernel = new StandardKernel();
kernel.Bind<IDependecy>()
.To<ConcreteDependency>()
.WhenInjectedInto<ClassA>()
.WithConstructorArgument("arg", "test");
var classA = kernel.Get<ClassA>();
Assert.IsNotNull(classA);
}
}
}
Test1不起作用,但Test2确实如此,我相信它们的行为应该相同。对我来说这看起来像个错误。由于某种原因,第一个测试无法通过以下错误解决依赖性:
Ninject.ActivationException:激活字符串时出错 没有匹配的绑定可用,并且该类型不可自绑定。 激活路径: 3)将依赖字符串注入到ConcreteDependency类型的构造函数的参数arg中 2)将依赖IDependecy注入到ClassA类型的构造函数的参数依赖性中 1)申请ClassA
我想如果第一次测试失败,第二次测试也会失败。我做错了吗?
谢谢!
答案 0 :(得分:2)
在Test1
中,您要调用的WithConstructorArgument
方法具有以下签名:
IBindingWithOrOnSyntax<T> WithConstructorArgument<TValue>(TValue value);
以下是文档中有关此方法的内容(您可以在IntelliSense上获得此内容):
表示应使用指定的值覆盖指定的构造函数参数。
以下是TValue
的文档:
指定要覆盖的参数类型
以下是value
的文档:
参数的值
所以,这一行:
.WithConstructorArgument(new ConstructorArgument("arg", "test"));
相当于(C#自动推断TValue
):
.WithConstructorArgument<ConstructorArgument>(new ConstructorArgument("arg", "test"));
告诉NInject ConcreteDependency
的构造函数的参数类型为ConstructorArgument
,实际上它的参数类型为string
。
所以你应该把它改成
.WithConstructorArgument<string>("test");
或更简单:
.WithConstructorArgument("test");
请注意,WithConstructorArgument
没有超载的参数类型为ConstructorArgument
。
但是,另一种名为WithParameter
的方法会引入IParameter
。
由于ConstructorArgument
实现了IParameter
,您可以使用此方法通过ConstructorArgument
指定构造函数参数,如下所示:
kernel.Bind<IDependecy>()
.To<ConcreteDependency>()
.WhenInjectedInto<ClassA>()
.WithParameter(new ConstructorArgument("arg", "test"));