2009-04-06 2 views
0

미디어 브라우저에는 공급자 모델이 있습니다. 이것은 기본적으로 각 엔터티에 대해 특정 순서로 호출되는 클래스 체인입니다. 공급자 체인에 주석을 달 수있는 가장 좋은 방법

그래서 예를 들어, 우리는이 :

 providers = new List<IMetadataProvider>(); 
     providers.Add(new ImageFromMediaLocationProvider()); 
     providers.Add(new ImageByNameProvider()); 
     providers.Add(new MovieProviderFromXml()); 
     providers.Add(new MovieDbProvider()); 
     providers.Add(new TVProviderFromXmlFiles()); 
     providers.Add(new TvDbProvider()); 
     providers.Add(new VirtualFolderProvider()); 
     providers.Add(new FrameGrabProvider()); 
     providers.Add(new MediaInfoProvider()); 

목록에서 공급자의 순서는 중요한 고차 공급자가 낮은 순서의 것들보다 우선합니다.

최근에이 부분을 확장 가능하도록 만들려고했습니다. 따라서 제 3 자 DLL은 자체 체인을 주입 할 자체 공급자를 정의 할 수 있습니다.

문제는 제 3자가 체인에 직접 삽입하도록 허용하면이 순서를 정의하기위한 중앙 위치를 잃게된다는 것입니다.

현재 약간의 불편 함이있는 현재 솔루션은 각 공급자마다 선택적 우선 순위 특성을 정의한 다음 우선 순위에 따라 순서를 지정하는 것입니다.

그래서 예를 들어 지금이 :이 제 3 자 체인에서의 위치를 ​​정의 할 수 있습니다

[ProviderPriority(20)] 
class ImageByNameProvider{} 

.

내가 생각한 또 다른 해결책은 예를 들어 속성 ​​예전과 후의 것입니다.

[Before(typeof(ImageByNameProvider))] 
class ImageFromMediaLocationProvider {} 

그러나이 프로그램이 더 쉽거나 어렵다고 확신 할 수 없습니다.

이 문제에 대한 다른 해결책이 있습니까? 어떤 해결책을 가지고 가겠습니까?

아마, 난 그냥 핵심 공급자에 대한 목록을 유지해야하고 ... 타사 공급자에 대한 attribs 후/전 실제로 해결해야 여기에 몇 가지 다른 문제가있는 것 같다

답변

1

을 추가합니다. 근본적인 문제는 그 목록의 중간에있는 임의의 지점에서 임의의 객체가 기존의 목록에 삽입 될 수있는 메커니즘을 생각해내는 것입니다.

IMetadataProvider 인터페이스의 실제 모습을 설명하지는 않지만 공급자를 고유하게 식별 할 수있는 방법이 있어야합니다 (최상의 옵션은 Guid를 사용하는 것입니다). 클래스 이름을 사용하는 것보다 이점은 리팩터링 중에 필요에 따라 클래스 이름을 바꿀 수 있다는 것입니다. 예를 들어 GUID를 동일하게 유지하는 한 사용자 지정 (제 3 자) 공급자에게 영향을 미치지 않으면 서 리팩터링하는 동안 클래스의 이름을 바꿀 수 있습니다.

당신은 아마 당신의 자신의 목록을 도출해야 오히려 간단한 목록을 사용하는 것보다 :

설치/그 목록에서 자신을 설치 제거하는 사용자 지정 (제 3 자) 공급 업체에 대한 방법을 노출
class ProviderList : List<IMetadataProvider { } 

. 이러한 메커니즘은 체인의 중간에 새 공급자를 삽입하는 방법을 알기에 충분히 똑똑해야하지만 삽입 된 여러 사용자 지정 공급자를 처리하는 방법을 알만큼 똑똑해야합니다. 마찬가지로 제거 프로세스는 비슷한 우려를 처리하고 누군가가 "핵심"공급자 중 하나를 제거하려고 시도하지 않도록 확실히 똑똑해야합니다.

좋은 방법은 나중에 삽입하려는 공급자의 Guid를 매개 변수로 Install() 메서드에 전달하는 것입니다.Remove() 메서드는 마찬가지로 공급자의 Guid를 제거합니다.

예를 들어, MovieProviderFromXml 다음에 새 공급자를 삽입한다고 가정 해보십시오. 그런 다음 다른 타사도 MovieProviderFromXml 다음에 새 공급자를 설치합니다. 새로운 사슬 주문은 무엇이되어야합니까? 두 번째 공급자는 항상 MovieProviderFromXml 바로 다음에 삽입합니까? 아니면 거기에서 시작합니까? 그러면 사용자 지정 공급자를 건너 뛰고 마지막 사용자 지정 공급자가 설치된 후 삽입합니다 (다음 "핵심"공급자 바로 앞에)?

관련 질문은 "핵심"공급자와 사용자 지정 공급자를 구별 할 수있는 방법이 필요합니다.

마지막으로 사용자 지정 공급자를 삽입 할 때 특히 체인에서 오류를 처리 할 수있는 방법이 있는지 확인해야합니다 잘못된 위치에 있습니다.

기본 체인의 기본 ("마스터") 목록을 항상 유지하려고합니다. 새 공급자가 설치된 경우 그 체인의 중간에 새로운 체인을 만들어야하지만 기본 체인을 풀고 싶지는 않습니다. 이렇게하면 체인을 다시 기본 상태로 재설정 할 수 있습니다.

우선 순위를 기반으로 체인을 연결하면 우선 순위 충돌을 처리하는 방법을 결정해야한다는 점에서 문제가 있습니다. Before/After 속성 집합까지 동일한 공급자에서 둘 다 허용 하시겠습니까? 아마 ChainInsert가 Enum 값으로 Before와 After를 정의하는 ChainInsert enum 속성을 가진 ProviderChainAttribute를 만드는 것이 더 합리적 일 수 있습니다. 이렇게하면 사용자 지정 공급자가 지정한 공급자 뒤에 또는 앞에 설치 여부를 결정하게 할 수 있습니다. 나는 여전히 형식보다는 Guid를 사용합니다.

이렇게하면이 문제에 접근하는 방법에 대한 다른 아이디어를 얻을 수 있기를 바랍니다.

+0

Scott, 시간과 사려 깊은 답변을 주셔서 감사합니다. 다음 날 또는 내 아이디어를 다룰 때 제 질문을 확장하려고합니다. 이것은 상당히 복잡한 문제입니다. +1 –

관련 문제