在C#中使用MEF(Managed Extensibility Framework)时,AggregateCatalog
类允许你组合多个目录,以便在单个目录中管理多个程序集中的组件。这对于跨多个程序集加载和发现组件非常有用。下面是如何使用AggregateCatalog
来组合多个目录的示例。
首先,确保你的各个程序集都包含使用[Export]
属性标记的组件。例如,你可能有一个程序集AssemblyA
包含:
// AssemblyA中的代码 | |
using System.ComponentModel.Composition; | |
namespace AssemblyA | |
{ | |
[Export(typeof(IMyExtension))] | |
public class ExtensionA : IMyExtension | |
{ | |
public void DoSomething() | |
{ | |
Console.WriteLine("ExtensionA.DoSomething()"); | |
} | |
} | |
} |
以及另一个程序集AssemblyB
包含:
csharp复制代码
// AssemblyB中的代码 | |
using System.ComponentModel.Composition; | |
namespace AssemblyB | |
{ | |
[Export(typeof(IMyExtension))] | |
public class ExtensionB : IMyExtension | |
{ | |
public void DoSomething() | |
{ | |
Console.WriteLine("ExtensionB.DoSomething()"); | |
} | |
} | |
} |
现在,在你的主程序或宿主应用程序中,你可以使用AggregateCatalog
来添加这些程序集的目录,并创建一个CompositionContainer
来加载这些组件:
csharp复制代码
using System; | |
using System.ComponentModel.Composition; | |
using System.ComponentModel.Composition.Hosting; | |
using System.Reflection; | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
// 创建AggregateCatalog实例 | |
var catalog = new AggregateCatalog(); | |
// 将AssemblyA的目录添加到AggregateCatalog中 | |
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetAssembly(typeof(AssemblyA.ExtensionA)))); | |
// 将AssemblyB的目录添加到AggregateCatalog中 | |
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetAssembly(typeof(AssemblyB.ExtensionB)))); | |
// 创建CompositionContainer并传入AggregateCatalog | |
using (var container = new CompositionContainer(catalog)) | |
{ | |
try | |
{ | |
// 满足导入(如果宿主类有导入的话) | |
container.ComposeParts(this); | |
// 获取并调用所有导出的IMyExtension实例 | |
var exports = container.GetExportedValues<IMyExtension>(); | |
foreach (var extension in exports) | |
{ | |
extension.DoSomething(); | |
} | |
} | |
catch (CompositionException compositionException) | |
{ | |
Console.WriteLine(compositionException.ToString()); | |
} | |
} | |
} | |
} |
在这个例子中,我们首先创建了一个AggregateCatalog
实例,然后使用AssemblyCatalog
将每个程序集的目录添加到其中。我们使用Assembly.GetAssembly
方法来获取每个类型的程序集,并传递给AssemblyCatalog
的构造函数。然后,我们创建了一个CompositionContainer
,并将AggregateCatalog
传递给它。最后,我们使用container.GetExportedValues<IMyExtension>()
来获取所有导出的IMyExtension
实例,并调用它们的DoSomething
方法。
请注意,AggregateCatalog
允许你动态地添加和删除目录。这意味着你可以在应用程序运行时添加或移除程序集,而不需要重新创建整个容器。此外,你还可以使用其他类型的目录,如DirectoryCatalog
(用于扫描文件系统中的程序集)或自定义目录类,并与AggregateCatalog
一起使用。