我尝试将一些代码从.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);
答案 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解决方法,而不是一个正确的解决方法,所以我不会接受这个答案。如果没有其他答案发布,这可能对其他人有用。