2013-09-30 5 views
2

당사의 제품 중 하나는 다양한 소형 웹 응용 프로그램과 각각 다른 컴퓨터에 잠재적으로 존재하는 Windows 서비스, 구성 요소로 구성됩니다. 그 중 하나는 WebForms 프로젝트입니다.이 프로젝트는 다른 모든 구성 허브 역할을합니다.DI를 사용하여 동일한 인터페이스의 여러 구현을 전달

우리는 이제 구성 요소의 일반 정보를 공개하는 기능을 설계하고 있습니다. 예를 들어이 같은 간단한 인터페이스를 상상해

public interface IStatistics 
{ 
    Statistics GetStatistics(); 
} 

우리는 모든 구성 요소에 동일한 인터페이스를 사용하려면, 그래서이 공통, 공유 어셈블리에 집중되어있다. 구현은 처음에는 동일하므로 인터페이스와 함께이 어셈블리에 있습니다.

다음은 공통 어셈블리에서 구현과 인터페이스를 모두 사용하여 각 구성 요소에 Wcf 서비스를 노출하는 것입니다. 구현은 로컬 시스템 시간과 같이 실행중인 위치에 따라 다른 결과를 반환하는 환경 클래스를 사용합니다.

내가 우아하게 해결하고자하는 문제는 같은 인터페이스를 사용하여 모든 구성 요소의 모든 구현을 webform에 전달하는 방법입니다.

우리는 현재 Unity을 사용하고 있지만 다른 DI 솔루션과 동일한 문제가 발생할 것이라고 생각합니다. 이 같은 인터페이스 (각 구성 요소마다 하나씩)를 5 개 구현하고 구성 요소별로 구별 할 수 있습니다 (Dictionary<Component, IStatistics>, ComponentEnum). 이는 페이지에서 어떤 구성 요소의 정보가 표시 될지 선택하기위한 드롭 다운이있을 것이므로 페이지는 올바른 구현을 호출하여 결과를 검색하기 때문에 필요합니다.

모든 구현에 명명 된 등록을 사용할 수 있다는 것을 알고 있습니다.

  1. 은 각각
  2. 명시 적으로 용기 내 웹 양식을 등록 할 구성 요소
  3. 등록 다른 이름으로 컨테이너의 각 구현을 가리키는 페이지의 5 개 가지 매개 변수가 있습니다 : Unfortunatelly,이에 나를 이끌 것 맞춤 InjectionConstructor 페이지 주입법

대한 올바른 순서로 각각 등록 인터페이스를 지정하여 I 유니티가 ResolveAll 메소드가 알고 있고, 따라서 하나를 수신 할 수있는 IStatistics[] 또는,하지만 그때 나는 그들을 차별화 할 수 없을 것입니다.

저는 MEF이 메타 데이터 인터페이스의 개념을 훌륭하게 해결한다고 생각합니다. 아마도이 문제에 MEF를 사용하는 것이이 문제를 해결할 수있는 방법일까요? 나는 이것이 우리가 말하는 wcf 대리인이기 때문에 여기서는 부적절하다고 생각합니다. 이것이 MEF와 어떻게 통합 될지는 볼 수 없습니다.

아마도 공장을 사용하는 것이 더 나은 전략 일 수 있지만 공장에서 서비스를 주입하는 방법을 알 수 없으므로 문제가 지속될 수 있습니다.

+1

네이밍이 문제라면'IStatistics' 구현체를'DisplayNameAttribute'로 꾸미는 것이 어떻습니까? 팩토리가 그 속성을 읽고'IEnumerable >'또는 비슷한 것을 반환하도록 할 수 있습니다. – Steven

+0

@Steven 제 질문에 필자는 구현이 실제로 전문화가 필요하지 않기 때문에 공통 어셈블리에 중앙 집중화되었다고 언급했음을 주목하십시오. 귀하의 접근 방식은 실제로 각 구성 요소에 여러 번 구현 한 경우에만 작동합니다. 현재로서는 이것이 의미가 없습니다. 통찰력을 가져 주셔서 감사합니다, 그렇지 않으면 아마 좋은 접근 방법 일 것입니다. – julealgon

+1

@ julealgon, 얼마나 많은 IStatistics 프록시가 있고 드롭 다운 목록에 표시 이름이 무엇인지 알 수 있습니까? –

답변

2

모든 것을 약간 다르게 디자인 할 수 있는지 궁금합니다. 나는 당신이하려고하는 것이 IoC가 무엇에 반대하고 있는지 생각합니다. 만약 당신이 올바르게 이해한다면, 같은 유형의 다섯 가지 인스턴스가 필요합니다.이 인스턴스는 어떻게 든 다른 유형의 다섯 가지 다른 객체와 관련 될 수 있습니다. 'IStatistics'는 공용 어셈블리에 정의 된 인터페이스입니다. 구현, 예를 들어 Statistics은 같은 어셈블리에 있습니다.다른 유형의 5 가지 인스턴스는 DI로 해결되고 직접 참조되지 않는 자체 '로컬'어셈블리에 정의됩니다. 여기

더 간단 수 있습니다 생각이며, 유지 보수 및 확장을 유지하면서 당신은 당신이 어떤 점에서 각 구성 요소 유형에 대한 다른 구현이 필요 특히, 필요한 달성 :

UML

DefaultStatisticsProvider 수 구성 요소가 IStatisticsProvider 인터페이스를 구현하는 데 사용됩니다. 공통 프로젝트에서 구현이 가능하기 때문에 여기에 관련된 DI는 없습니다.

public class DefaultStatisticsProvider : IStatisticsProvider 
{ 
    public Statistics GetStatistics() 
    { 
     var statistics = new Statistics(); 
     // Generate statistics data 
     return statistics; 
    } 
} 

구성 요소는 IStatisticProvider를 직접 구현하고 그들의 생성자에서 초기화 유형 DefaultStatisticsProvider의 개인 필드로 방법을 릴레이 :

public class ComponentA : IStatisticsProvider 
{ 
    private readonly DefaultStatisticsProvider _statisticsProvider; 

    public ComponentA() 
    { 
     _statisticsProvider = new DefaultStatisticsProvider(); 
    } 

    Statistics IStatisticsProvider.GetStatistics() 
    { 
     // You could change this implementation later to 
     // use a custom statistics provider 
     return _statisticsProvider.GetStatistics(); 
    } 
} 

지금 당신이 직접 IStatisticsProvider로 구성 요소를 등록 할 수 없다 어떤 종류의 인공 참조 표를 유지해야합니다. 유형을 통계 제공자 인스턴스와 관련시켜야합니다. 통계 제공자이므로 논리적 인 방식으로 나에게도 의미가 있습니다. (의사 코드)와 같은 뭔가 :

Container.Register<ComponentA>().As<IStatisticsProvider>(); 
Container.Register<ComponentB>().As<IStatisticsProvider>(); 

그래서

Container.ResolveAll<IStatisticsProvider>(); 

당신에게 줄 것이다

{ Instance of ComponentA, Instance of ComponentB } 

플러스, 언급 한 바와 같이, 어떤 점에서 당신이 제공하는 사용자 정의 구현을해야하는 경우 통계에는 재 설계가 전혀 필요하지 않습니다. 구성 요소의 GetStatistics() 구현을 변경하기 만하면됩니다.

+0

멋지게 답변;). 나중에 자세히 살펴 보겠다.하지만 OP의 요점은 코드를 불필요하게 중복하는 것을 피하는 것이 었습니다. 구현이 동일하므로 모든 구성 요소에 인터페이스를 구현하면 거의 얻을 수 없습니다. 또한 "드롭 다운 목록"에 구성 요소를 어떻게 제공하고이 방법을 사용하여 올바른 구현을 호출하는지 궁금합니다. 아마도이 부분에 대해 조금 자세히 설명해 주시겠습니까?어쩌면 당신의 아이디어와 Steven의 아이디어를 조합하여 구현에 대한 속성 (또는 심지어 피할 수있는 인터페이스의 속성)을 두는 것에 관한 것일 수도 있습니다. – julealgon

+0

또한 추가하고 싶습니다. 현재 공유 구성 요소의 원래 인터페이스를 상속 한 각 구성 요소마다 실제로 다른 인터페이스가 있습니다. 컨테이너의 등록을 차별화하고 모든 입력 된 구현을 웹 페이지로 전달할 수 있습니다. 이것은 의심 할 여지없이 매우 나쁜 해결책이지만, 내가 필요한 것을 위해 일하고있다. ( – julealgon

관련 문제