在我的应用程序的根目录下,我有一个AggregateCatalog和CompositionContainer,如下所示:
AggregateCatalog aggregateCatalog = new AggregateCatalog();
CompositionContainer compositionContainer = new CompositionContainer(aggregateCatalog);
我的应用程序加载了包含多个导出的模块,如下图所示。我想使用CompositionScopeDefinition来确定图中圈出的导出的范围。
See here for the class definitions.
// Create CompositionScopeDefinition.
TypeCatalog globalParts = new TypeCatalog(typeof(RequestListener));
TypeCatalog scopedParts = new TypeCatalog(typeof(RequestHandler), typeof(DataAccessLayer), typeof(Logger), typeof(DatabaseConnection));
CompositionScopeDefinition compositionScopeDefinition = new CompositionScopeDefinition(
globalParts,
new[] { new CompositionScopeDefinition(scopedParts, null) });
// Register CompositionScopeDefinition.
aggregateCatalog.Catalogs.Add(compositionScopeDefinition);
// Create an instance of RequestListener.
RequestListener requestListener = compositionContainer.GetExportedValue<RequestListener>();
但是,这导致以下异常:
如何将使用CompositionScopeDefinition的合并范围的导出添加到现有的AggregateCatalog并使用现有的CompositionContainer对其进行初始化?
更新
看来使用AggregateCatalog的问题。如果我直接将CompositionScopeDefinition添加到CompositionContainer,则一切正常,但这使我无法将其他目录添加到CompositionContainer。
最佳答案
我与在CodePlex上从事MEF工作的人交谈。从本质上讲,这就是他们的答案:
// Handy extension methods for dealing with CompositionScopeDefinition (Not relevant to this answer but useful).
public static class ComposablePartCatalogExtensions
{
public static CompositionScopeDefinition AsScope(this ComposablePartCatalog catalog, params CompositionScopeDefinition[] children)
{
return new CompositionScopeDefinition(catalog, children);
}
public static CompositionScopeDefinition AsScopeWithPublicSurface<T>(this ComposablePartCatalog catalog, params CompositionScopeDefinition[] children)
{
IEnumerable<ExportDefinition> definitions = catalog.Parts.SelectMany((p) => p.ExportDefinitions.Where((e) => e.ContractName == AttributedModelServices.GetContractName(typeof(T))));
return new CompositionScopeDefinition(catalog, children, definitions);
}
}
AggregateCatalog aggregateCatalog = new AggregateCatalog();
AggregateCatalog childAggregateCatalog = new AggregateCatalog();
CompositionScopeDefinition compositionScopeDefinition = aggregateCatalog.AsScope(childAggregateCatalog.AsScope());
CompositionContainer compositionContainer = new CompositionContainer(compositionScopeDefinition);
TypeCatalog globalParts = new TypeCatalog(typeof(RequestListener));
TypeCatalog scopedParts = new TypeCatalog(typeof(RequestHandler), typeof(DataAccessLayer), typeof(Logger), typeof(DatabaseConnection));
aggregateCatalog.Catalogs.Add(globalParts);
childAggregateCatalog.Catalogs.Add(scopedParts);
RequestListener requestListener = compositionContainer.GetExportedValue<RequestListener>();
本质上,您不能将CompositionScopeDefinition放在AggregateCatalog中。因此,您可以反转关系,并在根级别具有一个CompositionScopeDefinition,并为要表示的每个作用域级别提供多个AggregateCatalog。这似乎很棒。您还可以获得拥有单个CompositionContainer的额外好处。
关于c# - 使用CompositionScopeDefinition在MEF中定义范围,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16943121/