使用运行时定义的约定动态注册MEF导出

本文关键字:动态 注册 MEF 导出 约定 运行时 定义 | 更新日期: 2023-09-27 18:00:02

我正在尝试动态地(使用反射)向MEF目录添加类型,并在运行时定义导出约定。问题是MEF将简单地使用类型的完全限定名称作为约定,并且我需要将导出约定指定为特定的接口类型。

以下是我用来获取需要添加到MEF目录中的类型的代码:

private void RegisterSupportedRepositories(Func<ObjectContext> contextProvider)
    {
        var context = contextProvider();
        var properties = context.GetType().GetProperties();
        var entitySets = properties.Where(property => property.PropertyType.Name == typeof(ObjectSet<>).Name);
        foreach (var entitySet in entitySets)
        {
            var entityType = entitySet.PropertyType.GetGenericArguments()[0];
            var repositoryType = typeof(EFRepository<>).MakeGenericType(entityType);
            ComponentServices.RegisterComponent(repositoryType);                
        }
    }

组件服务。RegisterComponent定义如下,它获取一个AggregateCatalog(从不相关的地方),然后将TypeCatalogs添加到聚合目录:

public static void RegisterComponent(Type componentType)
    {
        var catalog = RetrieveCatalog();
        catalog.Catalogs.Add(new TypeCatalog(componentType));
    }

我需要能够将添加的类型的合同指定为接口,这通常可以通过如下的导出属性来完成:

[Export(typeof(IRepository<Customer>))]

问题是我如何动态添加这个导出约定,以便导出与上面显示的内容等效,而不是MEF从类型本身推断的默认"EFRepository"约定。

使用运行时定义的约定动态注册MEF导出

如果您可以使用CodePlex预览版的MEF,我建议您使用新的RegistrationBuilder来完成此操作。这是一篇描述它的博客文章:MEF的Convention Model

如果不能使用预览版本,可以使用ReflectionModelServices中的方法创建自己的零件定义,并创建使用它们的目录实现。