요즘 너무 블로깅을 안했더니 거미줄이...
본격적인 글은 정신적인 여유가 안되어서 못쓰겠고 대충 메모라도 휘갈겨놓으려고해요.
'가상의' 독자를 상대로 얘기하고는 있지만 기본적으로는 잊지 않으려고 쓰는 '메모'의 용도에요.
친절하지 않은 글이니 관심 없는 분은 그냥 패~스.

Prism + MefExtension을 사용하면 내부적으로 IModuleManager로 MefModuleManager를 사용하는데, 요놈은 XAP 파일에 대한 IModuleLoader로써 다시 MefModuleTypeLoader를 사용하죠. 또한 이 모듈타입로더는 내부적으로 MEF에서 기본으로 제공하는 DeploymentCatalog를 이용해요. ...아 이 무슨 구약적 이름 소개인가; 누가 누구를 낳고 누구는 누구랑 친척이고...;;

여튼;

프리즘의 모듈매니저는 기본적으로 각 모듈과의 의존성 관계를 설정하여 의존성 있는 모듈이 먼저 초기화(Initialize)되도록 처리를 해주는 훌륭한 매커니즘을 가지고 있죠.
문제는 MEF가 기본으로 제공하는 DeploymentCatalog.
요놈은 XAP파일의 URI를 던져주면 알아서 다운로드를 받아 XAP 파일 내에 들어있는 어셈블리들을 죄다 런타임에 불러들인 후 지정된 카탈로그에 ExportPart를 뽑아서 관리해주는 역할까지 수행하죠.
그런데 여기서 문제가 이놈은 다운로드가 완료되면 무조건 위의 동작을 수행한다는거에요.

만약 다음과 같은 의존성을 갖는 솔루션 구성일 경우...
  • 기반 모듈
    • 데이터처리 모듈
      • 이메일 모듈
      • SMS 모듈
    • 그래픽 모듈
'이메일 모듈'은 '데이터처리 모듈'보다 나중에 초기화가 되어야 하죠.
네 실제로 모듈매니저는 의존성 관계를 통해 '데이터처리 모듈'을 먼저 초기화해요.
그런데, DeploymentCatalog에 의해서 각 모듈들이 다운로드 될 때 '이메일 모듈'이 먼저 다운로드가 완료된다면?
내부적으로 '이메일 모듈'을 까뒤집어서 그 안에 있는 ExportPart를 뽑아내려고 시도할거에요.
이 과정에서 '이메일 모듈'이 가지고 있는 '데이터처리 모듈'에 대한 의존성이 문제가 되어 그 시도는 처절한 예외 메시지를 내뱉고는 뻗어버리죠.

혹시 DeploymentCatalog의 소스 코드를 열어보신 분이라면(MEF preview때이건 리플렉터로 까봤건) 아래의 부분이 문제의 그곳. DiscoverParts 메서드의 구현중 일부에요. 밑줄친 부분이 아직 의존성이 해결되었을지 어떨지 알 수 없는 파트를 접근하려는 곳.

foreach (Assembly assembly in assemblies)
{
    if (!dictionary.ContainsKey(assembly.FullName))
    {
        AssemblyCatalog catalog = new AssemblyCatalog(assembly);
        addedDefinitions.AddRange(catalog.Parts);
        dictionary.Add(assembly.FullName, catalog);
    }
}

휘유... 여기까지가 아래에 올린 Don't Panic의 내용을 재현한 거에요.
이게 적당히 다운로드 순서를 바꿔주는 것 만으로는 근본적인 해결이 안되네요.
아무래도 MEF의 DeploymentCatalog를 조금 바꿔서 써야겠어요.
그러려면;; 다시 이걸 사용하는 MefModuleManager를 바꿔야 하고 여기에 연관되어 있는 MefModuleInitializer, MefXapModuleTypeLoader도 모두 조금씩은 바꿔야겠죠; 하아...

그나마 소스 공개되어 있는게 얼마나 다행인지. 오픈소스 만세! 리플렉터 만만세!
저작자 표시 동일 조건 변경 허락
신고
Posted by gongdo


티스토리 툴바