MEF2如何使用基于约定的导入从CompositionHost导出中获取元数据
本文关键字:CompositionHost 导入 元数据 获取 何使用 于约定 约定 MEF2 | 更新日期: 2023-09-27 18:14:30
这是我的第一个SO问题,所以请原谅我…
我正在尝试使用ConventionBuilder类加载MEF2组件。一切都如预期的那样工作,直到我需要访问作为导入类型的属性可用的元数据。让我们假设我有以下类:
[RuntimeCheckAttribute("MyString1", "MyString2", MyEnum.Value1)]
class ImportedClass : IRuntimeCheck
{...}
现在我可以有一个convention builder实例为'IRunTimeCheck'的实例定义一个约定:
ConventionBuilder conventions = new ConventionBuilder();
conventions.ForTypesDerivedFrom<IRuntimeCheck>()
.Export(exp => exp.AsContractType<IRuntimeCheck>()).Shared();
然后我会使用一个'CompositionHost'实例,该实例已配置为检查程序集列表。对
的调用var runtimeChecks = container.GetExports<IRuntimeCheck>();
将创建所有导出的'IRuntimeCheck'类型的实例。
我现在的问题是如何在导出过程中访问iruntimecheck类型上的元数据。使用MEF1,我可以利用ImportMany/Lazy机制。到目前为止,我还没有找到一个很好的方法来重建MEF2的这种行为,因为'CompositionHost'上的所有导出重载都不允许我访问元数据属性。
我已经设法通过使用AddPartMetaData:
在ConventionBuilder级别添加元数据。conventions.ForTypesDerivedFrom<IRuntimeCheck>()
.AddPartMetadata("securityRuntimeMetadata", AddRuntimeCheckMetadata)
.Export(exp => exp.AsContractType<IRuntimeCheck>()).Shared();
private object AddRuntimeCheckMetadata(Type arg)
{
RuntimeCheckAttribute metadata = (arg.GetCustomAttributes<RuntimeCheckAttribute>(false) as
RuntimeCheckAttribute[]).FirstOrDefault();
if (metadata == null)
{
throw new InvalidOperationException("errorMessage");
}
return metadata;
}
当我调试MEF2代码时,我可以看到元数据信息是在约定构建器级别添加的。但是我不知道如何再次导出这个信息。我发现了几个试图利用ExportFactory的帖子。但他们中的大多数人都从事非共享出口,这不是我的目标。
正如我写的评论,我有一个类似的问题。经过一些尝试和代码步进,我得到了必要的元数据,而没有实例化类型。
这是我的ConventionBuilder配置:
var cb = new ConventionBuilder();
cb.ForTypesDerivedFrom<IHttpController>()
.AddPartMetadata(MetadataApiControllerName, t => t.FullName)
.Export(ex => ex.AddMetadata(MetadataApiControllerName, t => t.FullName))
.ExportInterfaces();
cb.ForTypesMatching(t => t.BaseType != null && (
(t.BaseType.Name.Equals(MetadataControllerName) && !t.BaseType.Name.StartsWith("T4MVC"))
|| t.BaseType.Name.Equals(MetadataExtentionControllerName)
))
.AddPartMetadata(MetadataControllerName, t => t.FullName)
.Export(ex => ex.AddMetadata(MetadataControllerName, t => t.FullName))
.ExportInterfaces();
我正在工作的MVC/Web Api项目,只需要一些控制器的一些元信息。为了得到它们,我使用Export:
var controllerExport = _compositionContainer.Container.Value.GetExports<ExportFactory<IController, IDictionary<String, Object>>>()
.FirstOrDefault(
part => part.Metadata != null &&
part.Metadata.ContainsKey(DefaultContainerConfiguration.MetadataControllerName) &&
part.Metadata.Any(v => v.Value.ToString()
.EndsWith(controllerName + ControllerNameByConvention, true,
CultureInfo.InvariantCulture)));
ExportFactory对象提供了所请求的元数据字典(IDictionary<String, Object>
)。