简体   繁体   English

如何过滤掉 MEF2 中的零件?

[英]How can you filter out parts in MEF2?

I'm trying to port some code from targeting the .NET Framework to .NET Core, and part of this involves switching from MEF1 to MEF2.我正在尝试将一些代码从 .NET Framework 移植到 .NET Core,其中一部分涉及从 MEF1 切换到 MEF2。 There doesn't seem to be a great deal of documentation on using MEF in .NET Core, and I can't find any examples demonstrating how to filter out parts as was possible with MEF1.似乎没有大量关于在 .NET Core 中使用 MEF 的文档,而且我找不到任何示例来演示如何像 MEF1 一样过滤掉部分。

In my original code (using MEF1), I wanted to load all parts exported from a set of assemblies except for MockCommunicationService .在我的原始代码中(使用 MEF1),我想加载从一组程序集导出的所有部件,但MockCommunicationService除外。 I implemented this as follows:我是这样实现的:

// 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);

What would the equivalent to this be in MEF2? MEF2 中的等效项是什么? I imagine that it probably involves using ConventionBuilder , but I don't know if there's a way to define a convention along the lines of "permit everything except x ".我想它可能涉及使用ConventionBuilder ,但我不知道是否有一种方法可以按照“允许除x之外的所有内容”来定义约定。

Ideally, something like this would be great:理想情况下,这样的事情会很棒:

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

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

It's hardly an optimal solution, but this is the workaround I've used for the time being.这几乎不是最佳解决方案,但这是我暂时使用的解决方法。

Looking at the source for ContainerConfiguration , I see that WithAssemblies is defined as:查看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);
}

So instead of using WithAssemblies , I use WithParts as follows:因此,我没有使用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();

Again, this seems more like a hacky workaround than a proper way to go about it, so I'm not going to accept this answer.同样,这似乎更像是一种骇人听闻的解决方法,而不是正确的解决方法,所以我不会接受这个答案。 If no other answers get posted this may be useful to others, though.不过,如果没有其他答案发布,这可能对其他人有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM