Catalog
Catalog 는 동적으로 Composable Part 를 찾아 Container 에 등록합니다. Composable Part 는 ExportAttribute 으로 Contract 를 선언할 수 있는데 개별적으로 일일이 Composable Part 를 등록하는 것은 너무나 큰 반복 작업이 될 수 있지만, MEF 의 Catalog 로 쉽게 자동적으로 등록을 할 수 있습니다.
Catalog 를 사용하지 않는 Composable Part 의 등록는 매우 고단한 작업입니다. 아래의 예제 소스 코드는 수동으로 Composable Part 를 등록하는 방법입니다.
예제에서는 단지 하나의 Export 를 등록하였지만 실제로 이러한 Composable Part 는 수십에서 수백개를 넘을 수 도 있습니다. 많은 Composable Part 를 동적이고 또는 자동적으로 등록해 주기 위해서 Catalog 를 사용하면 쉽게 해결할 수 있습니다.
이 외에도 Composable Part 를 Catalog 에 등록하는 여러 가지 방법이 있습니다. 아래는 MEF 에서 지원하는 Catalog 입니다.
Assembly Catalog
Assembly Catalog 는 닷넷 어셈블리를 Catalog 로 사용할 수 있습니다.
public AssemblyCatalog(string codeBase)
public AssemblyCatalog(Assembly assembly)
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); |
AssemblyCatalog 의 시그너처(Signature) 에서 보듯이 CodeBase 로 Catalog 를 사용할 수 있지만, 실버라이트에서는 CodeBase 를 지원하지 않으므로 실버라이트에서는 CodeBase 로 AssemblyCatalog 를 사용할 수 없습니다.
Directory Catalog
Directory Catalog 를 사용하면 특정 폴더의 어셈블리를 모두 검색하여 Composable Part 를 사용할 수 있습니다.
public DirectoryCatalog(string path)
public DirectoryCatalog(string path, string searchPattern)
Directory Catalog 는 내부적으로 System.IO 의 Directory.GetFiles() 메서드를 사용하여 지정한 폴더의 모든 어셈블리를 검색하도록 하여 Composable Part 를 가져오도록 합니다.
var catalog = new DirectoryCatalog("Addins"); |
기본적으로 *.DLL 확장자의 어셈블리만 검색하도록 설정되어있고, 어셈블리 파일의 검색 패턴을 지정하여 검색할 수 있습니다.
var catalog = new DirectoryCatalog("Addins", "*.exe"); |
아마 MEF 의 예제중에 XFileExplorer 처럼 특정 폴더에 어셈블리를 복사해 넣으면 자동으로 Composable Part 가 로드되는 예제가 있는데, 이것은 DirectoryCatalog 가 자동으로 처리해 주는 것이 아니라 FileSystemWatcher 클래스를 이용하여 직접 구현해야 합니다.
FileSystemWatcher 로 파일의 변경이 감지되면 DirectoryCatalog 의 Refresh() 메서드를 이용하여 폴더를 재검색 또는 새로고침을 할 수 있습니다.
Aggregation Catalog
Aggregation Catalog 는 복합적인 Catalog 를 사용할 수 있도록 합니다. 만약 Assembly Catalog 와 Directory Catalog 등을 동시에 사용하여 Composable Part 를 가져오도록 하려면 Aggregation Catalog 를 사용하면 됩니다.
public AggregateCatalog(params ComposablePartCatalog[] catalogs)
Aggregation Catalog 의 생성자는 params 로 인자를 받을 수 있습니다.
var catalog = new AggregateCatalog( new AssemblyCatalog(Assembly.GetExecutingAssembly()), new DirectoryCatalog(".")); |
Type Catalog
Type Catalog 는 Composable Part 를 Type 으로 개별적으로 사용하도록 합니다. 가장 단순하고 무식(?)한 방법일 수도 있지만 세세한 제어가 필요할 때 사용 가능한 Catalog 일 것 같습니다.
public TypeCatalog(params Type[] types)
public TypeCatalog(IEnumerable
var catalog = new TypeCatalog(typeof(EMailMessageSender), typeof(PhoneMessageSender)); |
Using catalog with a Container
이제 Catalog 를 Composable Container 에서 Composition 하도록 넘겨주는 일만 남았습니다.
public CompositionContainer()
public CompositionContainer(params ExportProvider[] providers)
public CompositionContainer(ComposablePartCatalog catalog, params ExportProvider[] providers)
var container = new CompositionContainer(catalog); |