2012-10-14 6 views
3

인터페이스가 이고 키가 있거나없는 등록을 허용하는 간단한 컨테이너가 있습니다.DI, 하나의 인터페이스 정의에 대해 여러 인스턴스 등록

프레임 워크가 등록 된 인스턴스를 내보기 모델의 생성자에 삽입 할 때 유용합니다.

이제 내 UI의 프레임으로 인해 여러 탐색 서비스를 사용할 수 있습니다. 그들은 모두 동일한 기본 인터페이스 (INavigationService)를 구현합니다.

매개 변수 (DI 등록 키)를 전달하지 않아도 컨테이너가 올바른 탐색 트리 (프레임 + 후속 뷰/뷰 모델)에 이러한 인스턴스를 주입 할 수 있기를 원합니다.

일반적으로 어떻게 이루어 집니까?

속성 기반 (즉, 등록 키를 모든 종속 클래스 정의에 적용)을 상상할 수 있습니다. 그러나 컨테이너는 이것을 지원하지 않습니다. 그것은 또한 번거 로움으로 보인다.

또한 태그 지정 전용 인터페이스를 만들 수도 있습니다. 따라서 INavigationService<T>을 입력하고 각 탐색 서비스를 다른 유형 인수로 등록하십시오. 예 : 프레임의 최초의 뷰의 형태 이것은 필자에게 필요한 해결책을 제공 할 것이지만, 나는 의미가없는 인터페이스를 지나칠 것이다. 한편

, 나는 또 다른 패턴이 있습니까?

+0

어떤 DI 라이브러리를 사용하고 있습니까? – GolfWolf

+0

@ w0lf : 컨테이너는 Caliburn.Micro (http://caliburnmicro.codeplex.com/SourceControl/changeset/view/3cc9a20b8554#src%2fCaliburn.Micro.WP71.Extensions%2fSimpleContainer.cs)의 일부입니다. – skarmats

답변

1

나는이 Caliburn 마이크로에 적용하는 방법을 잘 모르겠어요 FileTreeNavigation : INavigationService<FileTreeView>

같은 유형을 생성하여 (예를 들어 종속 뷰를 찾기위한 IDE 지원을받을 수 그러나 문제는 패턴에 관한 것이므로 여기에서 StrucureMap으로이 문제를 해결하는 방법을 설명합니다 : Ctor<> 메서드를 사용하여 생성자 매개 변수 해결을위한 구체적인 유형을 지정할 수있는 방법을 설명하겠습니다.

또한 특수 인터페이스 너의 FileTreeNavigation 예제)는 훌륭하지만, 어떤 이유로 든 적절한 것이 아니라면 계속 읽어보십시오.

의 우리가 있다고 가정하자 INavigationService 인터페이스와 두 개의 서로 다른 구현 :

public interface INavigationService { } 
public class NavigationServiceA : INavigationService { } 
public class NavigationServiceB : INavigationService { } 

다음, 우리는 두 개의 서로 다른 서비스 클래스, 모두 INavigationService 인터페이스에 따라이 : 마지막으로

public class ServiceA 
{ 
    private readonly INavigationService _navigationService; 

    public ServiceA(INavigationService navigationService) 
    { 
     _navigationService = navigationService; 
    } 
} 

public class ServiceB 
{ 
    private readonly INavigationService _navigationService; 

    public ServiceB(INavigationService navigationService) 
    { 
     _navigationService = navigationService; 
    } 
} 

을, 우리 IoC 컨테이너를 사용하여 해결할 클래스가 있습니다. 이 클래스는 모두 ServiceAServiceB에 따라 다음과 같이 정의된다 :

public class SomeClassToResolve 
{ 
    private readonly ServiceA _serviceA; 
    private readonly ServiceB _serviceB; 

    public SomeClassToResolve(ServiceA serviceA, ServiceB serviceB) 
    { 
     _serviceA = serviceA; 
     _serviceB = serviceB; 
    } 
} 

StructureMap 생성자 매개 변수를 해결하기 위해 사용하는 유형을 지정하는 가능성을 제공합니다. 지금

ForConcreteType<ServiceA>().Configure.Ctor<INavigationService>().Is<NavigationServiceA>(); 
ForConcreteType<ServiceB>().Configure.Ctor<INavigationService>().Is<NavigationServiceB>(); 

내가 container.GetInstance<SomeClassToResolve>();를 호출 할 때 ServiceA 올바르게 구성 ServiceB이 (NavigationServiceANavigationServiceB, 각각을 가진)의 인스턴스가 SomeClassToResolve의 인스턴스를 만들 수 있습니다 : 등록이 보이는 방법이다.

이 방법을 사용하면 훨씬 간단합니다. Conditional Construction의 가능성도 있습니다 만, 꽤 복잡해 질 수 있다고 생각합니다.

PS : 나는 StructureMap (해당 여기가 InjectionConstructor를 불렀다)와 함께하고 있어요 것과 비슷한 것 같다 내가 this approach 우연히 "caliburn 마이크로 생성자" 검색.

+0

정보 용 - PS에서 언급 한 예제는 DI 툴링을 기본 내장 도구와 다르게 사용합니다. 즉, Microsoft Unity 라이브러리 – skarmats

+0

종합적인 답변을 주셔서 감사합니다. 보다 완벽한 DI 솔루션을 선택할 때 StructureMap을 고려할 것입니다. WinRT 플랫폼에서 작업 중이므로 StructureMap은 실행 가능하지 않습니다. 하지만 이런 종류의 기능에 대해 매우 잘 알고 있습니다. 차별화는 실제 의존성의 차이에서 비롯된 것이므로 직접적인 문제는 인터페이스 솔루션이 더 마음에 듭니다. 'INavigationService'는 실제로 서로 다른 네비게이션 공간을 제어하기 때문에 서로 교환 할 수 없습니다. 인터페이스 유형을 호환되지 않게 만드는 것이 더 좋습니다. 그러나 나는 당신의 제안을 다른 용도로 볼 수있다. 나는 그것을 좋아한다. 감사합니다 – skarmats

+0

@skarmats 죄송합니다 - 나는 그것에 대해 인식하지 못했습니다 ('InjectionConstructor' 것). 예, 인터페이스를 분리하는 것이 가장 좋은 방법이라고 생각합니다. – GolfWolf

관련 문제