1

我正在尝试将一些针对 .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,但我不知道是否有一种方法可以按照“允许除x之外的所有内容”的方式定义约定。

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

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

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

1 回答 1

1

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

查看源代码ContainerConfiguration我看到它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 解决方法,而不是一种正确的解决方法,所以我不会接受这个答案。但是,如果没有发布其他答案,这可能对其他人有用。

于 2016-10-07T07:00:26.663 回答