2014-02-14 1 views
13

Simple Injector를 사용하면 해결할 때 생성자에 매개 변수를 전달할 수 있습니까? 나는이 두 프레임 워크가 Unity의 ResolverOverride 또는 DependencyOverride가하는 일을 모두 수행하는지 알고 싶습니다.Simple Injector를 사용하여 생성자에 매개 변수를 전달하는 방법은 무엇입니까?

+2

질문을 두 개의 분리 된 질문 (프레임 워크 당 하나씩)으로 나누는 것이 더 좋습니다. 이렇게하면 하나의 정답을 수락하기가 쉬워지고 나중에 다른 사람이 문제의 컨테이너에 대해이 정보를 쉽게 찾을 수 있습니다. – Steven

답변

14

자세한입니다 서비스가 실제로 해결 될 때.

은의 간단한 테스트 클래스를 설정하자

public interface IFoo 
{ 

} 

public class Foo : IFoo 
{ 
    public Foo(string value) 
    { 

    } 
} 

푸 클래스는 우리가 IFoo 서비스를 해석 할 때 공급하고자하는 문자열 인수를합니다.

var container = new ServiceContainer(); 
container.Register<string, IFoo>((factory, value) => new Foo(value)); 
var firstFoo = container.GetInstance<string, IFoo>("SomeValue"); 
var secondFoo = container.GetInstance<string, IFoo>("AnotherValue"); 

컨테이너를 직접 사용하지 않고 Foo 클래스의 새 인스턴스를 만들려면 단순히 함수 대리자를 삽입하면됩니다.

var container = new ServiceContainer(); 
container.Register<string, IFoo>((factory, value) => new Foo(value)); 
container.Register<IBar, Bar>(); 
var bar = container.GetInstance<IBar>(); 

문제가 생성자에 "정적"원시 값을 전달 대해 경우

는,이 단순히 같은 공장 대리자를 등록하여 수행됩니다

public interface IBar { } 

public class Bar : IBar 
{ 
    public Bar(Func<string, IFoo> fooFactory) 
    { 
     var firstFoo = fooFactory("SomeValue"); 
     var secondFoo = fooFactory("AnotherValue"); 
    } 
} 

은 "구성 루트는"지금과 같은 이.

var container = new ServiceContainer(); 
container.Register<IFoo>((factory) => new Foo("SomeValue")); 
var firstInstance = container.GetInstance<IFoo>(); 
var secondInstance = container.GetInstance<IFoo>(); 

다른 점은이 방법을 사용하면 해결 시간에 값을 전달할 수 없다는 것입니다. 값은 등록시 정적으로 지정됩니다.

+7

모든 것이 좋습니다. 난 그냥 라인을 좋아하지 않아 container.Register ((factory, value) => 새로운 Foo (value)); Foo가 컨테이너에 의해 주입되어야하는 IService1, ..., IServiceN과 같은 다른 종속성이 있다면 어떨까요? 난 그냥, 특정 매개 변수에 대한 특정 매개 변수를 사용하여 나머지 매개 변수 컨테이너에 대한 의존성을 제공해야한다고 말하고 싶습니다. 내가 어떻게 성취 할 수 있니? – user1325696

+1

'container.Register (factory) => 새로운 Foo (container.GetInstance ("SomeValue"))); – Marcello

+2

"foo"및 "bar"사용을 중단 할 수 있습니까? –

10

은 아마 Simple Injector에 가장 쉬운 옵션은 위임에 등록하는 것입니다

[Test] 
public void Test1() 
{ 
    Container container = new Container(); 

    container.Register<IClassWithParameter>(() => new ClassWithParameter("SomeValue")); 

    var result = container.GetInstance<IClassWithParameter>(); 
} 

public interface IClassWithParameter { } 

public class ClassWithParameter : IClassWithParameter 
{ 
    public ClassWithParameter(string parameter) 
    { 
    } 
} 

원시 종속성을 주입하기위한 고급 옵션은 내가이 질문은 생성자에 기본 값을 전달에 관한 것으로 의심 here

2

생성자가 다른 종속성이 없거나 이러한 종속성을 수동으로 해결하려는 경우 위의 작업이 모두 작동합니다. 이 아래로 떨어지면하지만 다음은 시나리오가있는 경우 :

public class Test : ITest 
{ 
    private IFoo _foo; 
    public Test(string parameter, IFoo foo) 
    { 
     _foo = foo; 
     .... 
    } 
} 

이제 당신은 수동으로 만 문자열뿐만 아니라 Foo를 주입 할 필요가 없습니다. 자 이제 의존성 주입을 사용하지 마십시오 (실제로). 또한 간단한 인젝터 상태 :

단순 주입기는 기본 유형 (예 : 정수 및 문자열)을 생성자에 주입 할 수 없습니다.

그래서 그들은 그렇게 말하지 않습니다.

또 다른 옵션은 "Extensibillity points" for this scenario입니다.지금 만약

_container.Register<ITest, Test>(); 
_container.RegisterInitializer<Test>(instance => {instance.Init("MyValue");}); 

: 이제 dependanices 당신의 하드 코딩 된 요소를 삽입 할 수

public class Test : ITest 
{ 
    private IFoo _foo; 
    public Test(IFoo foo) 
    { 
     _foo = foo; 
     .... 
    } 

    public void Init(string parameter) 
    { 

    } 
} 

:

당신이 당신의 주입 요소에서 추상적 인 하드 코딩 요소에 필요한이 작업을 수행하려면 다른 의존성을 추가하면 설정을 업데이트 할 필요없이 주입이 작동합니다.

public class Test : ITest 
{ 
    private IFoo _foo; 
    private IBar _bar; 
    public Test(IFoo foo, IBar bar) 
    { 
     _foo = foo; 
     _bar = bar; 
     .... 
    } 

    public void Init(string parameter) 
    { 

    } 
} 
관련 문제