我正在尝试将一些代码从针对.NET框架的代码移植到.NET核心,其中一部分涉及从MEF1切换到MEF2。关于在.NET核心中使用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);发布于 2016-10-07 07:00:26
这不是一个最佳的解决方案,但这是我目前使用的解决办法。
查看来源 for 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();再说一遍,这似乎更像是一个棘手的解决办法,而不是正确的方法,所以我不会接受这个答案。不过,如果没有其他答案被发布,这对其他人可能是有用的。
https://stackoverflow.com/questions/39868799
复制相似问题