Ninject - WithConstructorArgument 的重载行为很奇怪
Ninject - overloads for WithConstructorArgument behave weird
我有以下代码:
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 : Error activating string
No matching bindings are available, and the type is not self-bindable.
Activation path:
3) Injection of dependency string into parameter arg of constructor of type ConcreteDependency
2) Injection of dependency IDependecy into parameter dependecy of constructor of type ClassA
1) Request for ClassA
我想如果第一个测试失败,第二个测试也应该失败。我做错了什么吗?
谢谢!
在 Test1
中,您正在调用的 WithConstructorArgument
方法具有以下签名:
IBindingWithOrOnSyntax<T> WithConstructorArgument<TValue>(TValue value);
以下是文档中关于此方法的内容(您可以在 IntelliSense 上获得):
Indicates that the specified constructor argument should be overridden with the specified value.
这里是 TValue
的文档:
Specifies the argument type to override
这里是 value
的文档:
The value for the argument
所以,这一行:
.WithConstructorArgument(new ConstructorArgument("arg", "test"));
相当于(C# 自动推断 TValue
):
.WithConstructorArgument<ConstructorArgument>(new ConstructorArgument("arg", "test"));
告诉 NInject ConcreteDependency
的构造函数有一个 ConstructorArgument
类型的参数,而实际上它有一个 string
.[=34 类型的参数=]
所以你应该把它改成
.WithConstructorArgument<string>("test");
或更简单:
.WithConstructorArgument("test");
请注意,没有 WithConstructorArgument
的重载具有 ConstructorArgument
.
类型的参数
然而,还有另一种名为 WithParameter
的方法接受 IParameter
.
由于 ConstructorArgument
实现了 IParameter
,您可以使用此方法通过 ConstructorArgument
指定构造函数参数,如下所示:
kernel.Bind<IDependecy>()
.To<ConcreteDependency>()
.WhenInjectedInto<ClassA>()
.WithParameter(new ConstructorArgument("arg", "test"));
我有以下代码:
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 : Error activating string No matching bindings are available, and the type is not self-bindable. Activation path: 3) Injection of dependency string into parameter arg of constructor of type ConcreteDependency 2) Injection of dependency IDependecy into parameter dependecy of constructor of type ClassA 1) Request for ClassA
我想如果第一个测试失败,第二个测试也应该失败。我做错了什么吗?
谢谢!
在 Test1
中,您正在调用的 WithConstructorArgument
方法具有以下签名:
IBindingWithOrOnSyntax<T> WithConstructorArgument<TValue>(TValue value);
以下是文档中关于此方法的内容(您可以在 IntelliSense 上获得):
Indicates that the specified constructor argument should be overridden with the specified value.
这里是 TValue
的文档:
Specifies the argument type to override
这里是 value
的文档:
The value for the argument
所以,这一行:
.WithConstructorArgument(new ConstructorArgument("arg", "test"));
相当于(C# 自动推断 TValue
):
.WithConstructorArgument<ConstructorArgument>(new ConstructorArgument("arg", "test"));
告诉 NInject ConcreteDependency
的构造函数有一个 ConstructorArgument
类型的参数,而实际上它有一个 string
.[=34 类型的参数=]
所以你应该把它改成
.WithConstructorArgument<string>("test");
或更简单:
.WithConstructorArgument("test");
请注意,没有 WithConstructorArgument
的重载具有 ConstructorArgument
.
然而,还有另一种名为 WithParameter
的方法接受 IParameter
.
由于 ConstructorArgument
实现了 IParameter
,您可以使用此方法通过 ConstructorArgument
指定构造函数参数,如下所示:
kernel.Bind<IDependecy>()
.To<ConcreteDependency>()
.WhenInjectedInto<ClassA>()
.WithParameter(new ConstructorArgument("arg", "test"));