gpt4 book ai didi

c# - 使用 CompositionScopeDefinition 在 MEF 中定义范围

转载 作者:太空狗 更新时间:2023-10-29 17:58:20 25 4
gpt4 key购买 nike

在我的应用程序的根目录下,我有一个 AggregateCatalog 和一个 CompositionContainer,如下所示:

AggregateCatalog aggregateCatalog = new AggregateCatalog();
CompositionContainer compositionContainer = new CompositionContainer(aggregateCatalog);

我的应用程序加载了包含多个导出的模块,如下图所示。我想使用 CompositionScopeDefinition 来确定图中圈出的导出范围。

Module Export Diagram

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>();

但是,这会导致以下异常:

System.ComponentModel.Composition.ImportCardinalityMismatchException occurred Message=No exports were found that match the constraint: ContractName MyNamespace.RequestListener RequiredTypeIdentity MyNamespace.RequestListener InnerException:

如何使用 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com