2010-02-13 7 views
2

현재 내가 Unity를 사용하는 동안 작은 유틸리티를 작성 중이므로이 문제를 해결할 수 있다면 다른 IoC 컨테이너로 변경할 수 있습니다.변경 불가능한 클래스 및 화합 응용 프로그램 블록

내가 만들 때 일부 데이터를 제공하는 클래스를 만들려하지만, 그 이후 불변, 일반적으로 내가 함께 할 것입니다 : 생성자에서 SomeHashingClass에 대한 종속성이

class SomeItem 
{ 
    public SomeItem(string name) 
    { 
     Name = name; 
     Hash = new SomeHashingClass().GenerateHash(name); 
    } 

    public string Name { get; private set; } 

    public string Hash { get; private set; } 
} 

문제입니다 , 개체를 불변으로 유지하는 동안 어떻게 삽입합니까?

한 가지 방법은 생성자에 의존성을 적용한 다음 현재 생성자와 동일한 메소드를 사용하여 실제 작업을 수행하는 것입니다. 그러나 개체가 기존의 상태로 남을 수는 있지만 완전히 무효라는 생각은 싫다. 그리고 메서드를 한 번만 호출 할 수 있도록 코드를 작성해야합니다.

class SomeItemFactory 
{ 
    IHashingClass _hashingClass; 

    public SomeItemFactory(IHashingClass hashingClass) 
    { 
     _hashingClass = hashingClass; 
    } 

    public SomeItem Create(string name) 
    { 
     return new SomeItem(_hashingClass, name); 
    } 
} 

class SomeItem 
{ 
    public SomeItem(IHashingClass hashingClass, string name) 
    { 
     Name = name; 
     Hash = hashingClass.GenerateHash(name); 
    } 

    public string Name { get; private set; } 

    public string Hash { get; private set; } 
} 

하십시오 : 나는 통일이 수동 SomeItem에 대한 의존성 주입을하고, 해결하는 것이 그것이 'SomeItemFactory'클래스를 만드는 것입니다해야 볼 수있는 다른 방법은, 그러나 이것은 코드의 양을 두 배로

이것을 할 수있는 깨끗한 방법이 있다고 말해주세요. 왜 같은 방법이 없습니다 :

unityContainer.Resolve<SomeItem>("the items name"); 

답변

3

실제로 매개 변수를 Resolve 메서드에 전달할 수 있지만 이것이 실제로 올바른 디자인인지주의 깊게 고려하십시오.

왜 처음부터이 작업을 수행 하시겠습니까? 유니티를 서비스 로케이터로 사용하고 싶기 때문입니까? 그게 내가 생각할 수있는 유일한 이유지만, I consider this an anti-pattern.

DI 컨테이너의 사용은 할리우드 원칙을 따라야합니다 : resolve the entire application graph at the Composition Root으로 말한 다음 모든 것을 잊어 버려야합니다. 특정 경우

, 당신은 그대로 SomeItem을 유지 할 수 있습니다,하지만 당신은 종속성으로 HashingClass을 변화 할 수 있도록하려면, 당신은 SomeItem에 주입해야하고, 생성자 삽입는 최선의 방법입니다.

응용 프로그램에서 하나의 SomeItem 인스턴스 만 필요하면 Unity 에서처럼 SomeItem 인스턴스를 연결할 수 있지만 여러 인스턴스를 만들어야하는 경우 Abstract Factory is the correct approach입니다.

예제가 거의 있습니다. SomeItemFactory에서 인터페이스를 추출하고 SomeItem 인스턴스를 생성해야하는 소비자의 ISomeItemFactory에 종속성을 적용하면됩니다.

더 많은 코드처럼 보일 수 있지만 코드 줄은 어떤 경우에도 (어떤 방향 으로든 다른 방향 으로든) 코드 품질에 특히 좋은 척도는 아닙니다.그러나이 방법을 사용하면 Single Responsibility Principle을 따르고 SomeItem의 생성 및 해싱을 서로 독립적으로 변경할 수 있습니다.

은 Unity에만 특별히 적용되는 것이 아니라 일반적으로 DI에 광범위하게 적용됩니다.

0

당신이 설정에서

unityContainer.Resolve<ISomeInterface>("MyMappingName"); 

연합 말하는대로 설정 파일을 사용하는 가정 할 수있다, 당신은 할 수 있습니다

<typeAliases> 
    <typeAlias alias="SomeInterface" type="ISomeInterface, SomeAssembly" /> 
    <typeAlias alias="SomeConcreteType" type="SomeType, SomeAssembly" /> 
</typeAliases> 

<containers> 
    <container> 
     <type type="SomeInterface" mapTo="SomeConcreteType" name="MyMappingName" /> 
    </container> 
</containers> 
관련 문제