如何过滤掉MEF2中的零件?

时间:2016-10-05 08:19:45

标签: c# mef .net-core mef2

我尝试将一些代码从.NET Framework定位到.NET Core,其中一部分涉及从MEF1切换到MEF2。似乎没有关于在.NET Core中使用MEF的大量文档,我无法找到任何演示如何过滤部分的示例,如MEF1所示

在我的原始代码中(使用MEF1),我想加载从MockCommunicationService以外的一组程序集中导出的所有部件。我按如下方式实现了这个:

// Filter out invalid exports.
Func<ComposablePartDefinition, bool> partFilter = it => !it.ToString().Contains(nameof(MockCommunicationService));

var assemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var catalog = new DirectoryCatalog(assemblyPath).Filter(partFilter);
var container = new CompositionContainer(catalog);

在MEF2中相当于什么?我想它可能涉及使用ConventionBuilder,但我不知道是否有一种方法可以按照&#34的方式定义约定;允许除 x &#34;

理想情况下,这样的事情会很棒:

var conventions = new ConventionBuilder();
conventions.ForType<MockCommunicationService>().SuppressExports();

var configuration = new ContainerConfiguration()
    .WithAssemblies(assemblies, conventions);

1 个答案:

答案 0 :(得分:1)

这不是最佳解决方案,但这是我暂时使用的解决方法。

查看ContainerConfiguration的{​​{3}},我看到WithAssemblies定义为:

public ContainerConfiguration WithAssemblies(IEnumerable<Assembly> assemblies, AttributedModelProvider conventions)
{
    if (assemblies == null) throw new ArgumentNullException(nameof(assemblies));
    return WithParts(assemblies.SelectMany(a => a.DefinedTypes.Select(dt => dt.AsType())), conventions);
}

所以我没有使用WithAssemblies,而是使用WithParts,如下所示:

// Filter out invalid exports.
Predicate<Type> filterParts = part => !part.Equals(typeof(MockCommunicationService));

var parts = from name in DependencyContext.Default.GetDefaultAssemblyNames()
            where name.Name.StartsWith("<<Company>>")
            let assembly = Assembly.Load(name)
            from definedType in assembly.DefinedTypes
            let part = definedType.AsType()
            where filterParts(part)
            select part;

var configuration = new ContainerConfiguration()
    .WithParts(parts);

return configuration.CreateContainer();

同样,这似乎更像是一个hacky解决方法,而不是一个正确的解决方法,所以我不会接受这个答案。如果没有其他答案发布,这可能对其他人有用。