2012-06-27 3 views
4

Ninject 팩토리 확장을 사용하면 팩토리를 자동으로 생성하고 팩토리가 매개 변수를 클래스의 생성자에 전달할 수 있습니다. 다음 테스트에 통과 :팩토리 매개 변수를 종속성으로 전달할 수 있도록 ninject 팩토리 확장자 가져 오기

:

public interface IBar 
{ 
    int Foo { get; } 
} 

public class Bar : IBar 
{ 
    int _foo; 
    public Bar(int foo) { _foo = foo; } 
    public int Foo { get { return _foo; } } 
} 

public interface IBarFactory 
{ 
    IBar CreateTest(int foo); 
} 

[Test] 
public void ExecuteTest() 
{ 
    var kernel = new StandardKernel(); 
    kernel.Bind<IBar>().To<Bar>(); 
    kernel.Bind<IBarFactory>().ToFactory(); 
    var factory = kernel.Get<IBarFactory>(); 
    var actual = factory.CreateTest(42); 
    Assert.That(actual, Is.InstanceOf<Bar>()); 
} 

하지만, 내 특정 문제에, 나는 이런 내가 건설하고있어 클래스가 아닌 클래스 자체의 의존성에 공장 인수를 전달하는 데 싶습니다

Ninject.ActivationException : : 오류가 일치 바인딩하는 int 활성화 사용할 수 있으며, 유형 자기 바인딩되지 않습니다

public interface IBarContainer 
{ 
    IBar Bar { get; } 
} 

public class BarContainer : IBarContainer 
{ 
    IBar _bar; 
    public BarContainer(IBar bar) { _bar = bar; } 
    public IBar Bar { get { return _bar; } } 
} 

public interface ITestContainerFactory 
{ 
    IBarContainer CreateTestContainer(int foo); 
} 

[Test] 
public void ExecuteTestContainer() 
{ 
    var kernel = new StandardKernel(); 
    kernel.Bind<IBar>().To<Bar>(); 
    kernel.Bind<IBarContainer>().To<BarContainer>(); 
    kernel.Bind<ITestContainerFactory>().ToFactory(); 
    var factory = kernel.Get<ITestContainerFactory>(); 
    var actual = factory.CreateTestContainer(42); 
    Assert.That(actual.Bar, Is.InstanceOf<Bar>()); 
} 

이 테스트는 메시지와 함께 실패합니다. 활성화 경로 : 형 막대의 생성자 파라미터 foo에에 의존 INT의
가 3) 주입
2) IBarContainer

용 형 BarContainer의 생성자
1) 요청 파라미터 줄에 종속 IBar 사출

인가 거기에 'Bar'의존성을 해결할 때 전달 된 'foo'인수를 사용하려고한다는 것을 공장에서 알아낼 수있는 방법이 있습니까?

답변

3

사용하여, 기본적으로 지원됩니다 previous answer을 기반으로합니다.

+0

이 정보를 제공해 주셔서 감사합니다. 이것은 내장 된 기능을 사용하기 때문에 받아 들여진 대답이어야합니다. – McLovin

4

Hy, 기본 인스턴스 공급자는 상속 된 생성자 인수를 사용하지 않습니다. 당신은 다음과 같이 자신의 인스턴스 제공자를 작성하여이 동작을 변경할 수 있습니다

public class CustomInstanceProvider : StandardInstanceProvider { 
    protected override ConstructorArgument[] 
     GetConstructorArguments(MethodInfo methodInfo, object[] arguments) 
     { 
      var parameters = methodInfo.GetParameters(); 
      var constructorArguments = 
       new ConstructorArgument[parameters.Length]; 
      for (int i = 0; i < parameters.Length; i++) 
      { 
       constructorArguments[i] = 
        new ConstructorArgument 
         (parameters[i].Name, arguments[i], true); 
      } 
      return constructorArguments; 
     } 
} 

그런 다음 당신은 단지 대신 제공의 자신을 사용하는 것이 Ninject에 지시해야합니다. 내가 제대로 질문을 이해 해요 경우

1

을하는 데 도움이

희망, 나는 확장 결합()이 Ninject에 위키 문서에서는 새로운 .ToFactory을 사용하는 방법에 대한 좋은 예 (Factory interface)을 가지고 있다고 생각하고, 어떻게 생성 된 팩토리에서 생성자가 매개 변수를 가진 객체를 만들도록하십시오. 당신이 source code 보면,

kernel.Bind<IxxxFactory>() 
    .ToFactory(() => new TypeMatchingArgumentInheritanceInstanceProvider()); 

:

Ninject.Extensions.Factory.TypeMatchingArgumentInheritanceInstanceProvider 

당신은 다음과 같이 사용할 수 있습니다 : Ninject.Extensions.Factory이 버전 3.2.0에서