2017-12-19 4 views
2

예 :Unity 컨테이너가있는 DI - 추가 매개 변수로 해결되는 모범 사례?

IApple 및 구현 Apple. Apple의 생성자 :

public Apple(IVitamin vitamin, int size)

나는 모든 DI를 등록 할 수 있습니다 IApple :

container.RegisterType<IApple,Apple>(); 
container.RegisterInstance<IVitamin>(vitamin); 

INT 크기 매개 변수 삽입 사과의 인스턴스를 생성 할 때 내가 지금 매개 변수를 재정의 할 수

var apple = container.Resolve<IApple>(new ParameterOverrides<Apple> {{"size", 9001}} 

거기에 매개 변수의 문자열 ("크기")을 써야한다는 것이 귀찮은 것 같습니다. 다른 매개 변수가 관련되어있을 때 DI를 수행하는 것이 가장 바람직한 방법입니까? 아니면 그걸 처리하는 AppleFactory (또는 일반적으로 공장)를 만들어야합니까? (이. 비 DI 속성뿐만 아니라 DI의 사람이있는 모든 클래스의 공장을 작성해야하는 과잉

보인다 또는 당신은 무시하고 수동으로 속성을 설정하지 않겠습니까?

var apple = container.Resolve<IApple>(); 
apple.Size = 9001; 

은이 방법을 코드 로직은 재산의 세터에 생성자에서 전송 될 것이다.

답변

3

당신이 거기에 ("크기")

을 매개 변수의 문자열을 작성해야한다는 귀찮은 것

예,보기 흉하지만, 적어도 Unity와는 관련이 없습니다.

이 아닌 DI 속성뿐만 아니라

진정한 DI의 사람이있는 모든 클래스의 공장을 작성해야하는 잔인한 것 같다,하지만 당신은 어쨌든 무엇을해야하는지 아마. 대부분의 코드는 컨테이너에 직접 의존해서는 안됩니다. 당신이 공장을 만들 경우 대신 문자열의 nameof를 사용할 수 있기 때문에

는 매개 변수의 재정은 매우 추악한되지 않습니다 :

대체 내 Unity.Extras.AutoFactory 확장자를 사용하지만, 마음에 유지하는 것입니다
class AppleFactory : IAppleFactory 
{ 
    ... 

    public IApple CreateApple(int size) 
    { 
     return _container.Resolve<IApple>(new ParameterOverrides<Apple> {{nameof(size), size}}; 
    } 
} 

그것은 알파 상태에있어 ...

+0

나는 항상 아래에 "특별한"인스턴스화를해야 할 때 공장을 사용한다고 생각했습니다. 따라서 ... = new X()를 호출하는 것은 모든 것이 저장되는 팩토리를 사용하는 동안 중요합니다. DI 컨테이너를 사용할 때 클래스의 60 %에 대해 공장을 생성해야하는 것처럼 들리지만 .... – Thypari

1

나는 왜 그런 식으로 클래스에 integer을 삽입하겠습니까? 화합을 사용하여 인스턴스화 된 모든 Apple에 동일한 값이 주입되면 값은 상수입니까? 그렇다면 실제로 주입 할 필요가 없습니다. 그것은 단지 Apple의 일부일 수 있습니다. 그러나 귀하의 예에서 Apple이 상태가있는 엔티티 또는 객체를 나타내며 크기가 다를 수 있다면 Factory은 확실히 더 나은 옵션처럼 보입니다. Factory은 초기화하는 동안 속성 값을 설정하게됩니다. 코드를 테스트하는 경우 이러한 종류의 결정을 Factory으로 옮기고 IoC 컨테이너 구성이 객체의 초기 상태에 대한 값을 다루는 대신 종속성 트리 작성에 초점을 맞추도록하는 것이 좋습니다.

+0

이 예제에서는 공장이 분명히 더 나은 옵션입니다. 해결해야 할 AppleWork를 생각해보십시오. AppleWorker는 항상 동일한 구현이지만 매번 다른 Apple을 사용해야합니다. 작업자는 어떤 종류의 사과도 신경 쓰지 않고 항상 똑같이 작동합니다. 공개 AppleWorker (ITool 도구, Apple 사과). 따라서 ITool은 DI가 해결되고 사과가 방금 전달됩니다. – Thypari

+0

AppleWorker는 오직 Apple 만 취급 할 것으로 기대하십니까? 그렇지 않다면 주입 방법이 더 적절하게 들린다. 그런 식으로 사과를 근로자에게 전달해야한다는 결정은 근로자에게 Apple과의 협력을 요청하는 수업/방법과 관련이 있습니다. AppleWorker (ITool 도구) 및 _appleWorker.DoWork (apple) – RVid

+0

내가 찾고있는 솔루션처럼 보입니다. 하지만 이런 식으로 제 DoWork (Apple apple) 클래스는 생성자에서 이전에 사용 된 사과를 사용하는 모든 초기화 작업을 수행해야합니다. 예 : AppleAnalyzer 분석기 = 새로운 AppleAnalyzer (사과); 또는 AppleAnalyser를 단일성에 등록해야합니다. 그러면 속성을 전달해야하는 원래 문제부터 시작합니다. – Thypari

1

예제가 너무 단순하다고 생각합니다.크기가 다른 사과를 만들려면 컨테이너에서 사과를 해결하지 않을 것입니다 (사과를 만드는 방법과 조금 이상합니다. factory, container) .

컨테이너의 주 목적은 컨테이너의 현재 상태에서 생성 할 수 있어야하는 복잡한 오브젝트 구성/종속성을 연결하는 것임을 잊지 마십시오. Resolve 메서드에 대한 인수를 제공하는 것을 발견하면 중단하고 피하려고 시도합니다. 아마도 일부 재 설계가 필요할 것이므로 리팩토링이 올바른 방향입니다.

사이드 참고 : 대부분의 경우에

내가 지금은 containerAppleSize의 인스턴스를 등록 할 수 있습니다이

public struct AppleSize { 
    public int Value { get; } 
    ..... 
} 

같은 구조체/클래스 뭔가를 사용하는 것이 기본 주입 할 필요가 Apple 생성자는 int 대신 AppleSize을 사용합니다. 프리미티브의 등록을 피하십시오. 더 유용한 구조체/클래스 정의를 사용하십시오.

시나리오가 더 많은 경우 복잡한 (원시 너무 많은 인자에 의존 할 수 주입/계산 조작 할 필요가 예정) 후 내가 factory 객체의 생성과 관련된 모든 작업을 캡슐화 에 만들 것 이것은 내가 생각하는 시나리오에 더 가깝습니다.