2015-12-08 16 views
1

我有以下代碼:Ninject - 重載WithConstructorArgument行爲怪異

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

的測試1不起作用,但確實的Test2,我相信他們應該具有相同的行爲。它看起來像一個bug。出於某種原因,第一次測試無法解析的依賴性並出現以下錯誤:

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

我想,如果第一個測試失敗的第二個應該失敗了。難道我做錯了什麼?

謝謝!

回答

2

Test1,該WithConstructorArgument方法要調用具有以下特徵:

IBindingWithOrOnSyntax<T> WithConstructorArgument<TValue>(TValue value); 

這裏是什麼文件說,有關此方法(你得到這個在智能感知):

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類型的參數,其中實際上它具有t的參數YPE string

所以,你應該將其更改爲

.WithConstructorArgument<string>("test"); 

或者簡單:

.WithConstructorArgument("test"); 

請注意,不存在超載WithConstructorArgumentConstructorArgument類型的參數。

然而,還有另一種稱爲WithParameter方法,該方法在IParameter

由於ConstructorArgument實現IParameter,您可以通過ConstructorArgument使用此方法來指定構造函數的參數是這樣的:

kernel.Bind<IDependecy>() 
    .To<ConcreteDependency>() 
    .WhenInjectedInto<ClassA>() 
    .WithParameter(new ConstructorArgument("arg", "test"));