首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MEF2如何使用基于约定的导入从CompositionHost导出中获取元数据

MEF2如何使用基于约定的导入从CompositionHost导出中获取元数据
EN

Stack Overflow用户
提问于 2014-07-24 21:34:58
回答 1查看 1.7K关注 0票数 4

这是我的第一个问题,所以请容忍我…

我正在尝试使用ConventionBuilder类加载带有MEF2的组件。在我需要访问作为导入类型的属性可用的元数据之前,一切都是预期的。让我们假设我有以下类:

代码语言:javascript
复制
[RuntimeCheckAttribute("MyString1", "MyString2", MyEnum.Value1)]
class ImportedClass : IRuntimeCheck
{...}

现在我可以有一个ConventionBuilder实例来定义‘IRunTimeCheck’实例的约定:

代码语言:javascript
复制
ConventionBuilder conventions = new ConventionBuilder();
conventions.ForTypesDerivedFrom<IRuntimeCheck>()
           .Export(exp => exp.AsContractType<IRuntimeCheck>()).Shared();

然后,我将使用一个'CompositionHost‘实例,该实例已配置为检查程序集列表。调用

代码语言:javascript
复制
var runtimeChecks = container.GetExports<IRuntimeCheck>();

然后将创建所有导出的“IRuntimeCheck”类型的实例。

我现在的问题是如何在导出过程中访问IRunTimeCheck-types上的元数据。使用MEF1,我可以利用ImportMany / Lazy机制。到目前为止,我还没有找到用MEF2重新构建此行为的好方法,因为'CompositionHost‘上的所有导出重载都不允许我访问元数据属性。

我已经设法通过使用AddPartMetaData在ConventionBuilder级别添加了元数据:

代码语言:javascript
复制
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的文章。但他们中的大多数都在使用非共享导出,这不是我的目标。

EN

回答 1

Stack Overflow用户

发布于 2014-08-20 17:34:30

在我写评论的时候,我也遇到了类似的问题。经过一些尝试和代码单步执行之后,我在没有实例化类型的情况下获得了必要的元数据。

这是我的ConventionBuilder配置:

代码语言:javascript
复制
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项目,只需要一些控制器的元信息。为了获得它们,我使用这个导出:

代码语言:javascript
复制
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>)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24935261

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档