2016-10-05 2 views
1

Я пытаюсь перенести некоторый код из таргетинга .NET Framework в .NET Core, а часть этого включает переход от MEF1 к MEF2. По-видимому, не существует большой документации по использованию MEF в .NET Core, и я не могу найти примеров, демонстрирующих, как отфильтровать, как это было возможно с помощью MEF1.Как вы можете отфильтровать части в MEF2?

В моем исходном коде (с использованием 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); 

ответ

1

Это вряд ли можно назвать оптимальным решением, но это временное решение я использовал на некоторое время.

Глядя на the source для 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(); 

Опять же, это больше похоже хакерское обходное решение, чем правильное решение, поэтому я не буду принимать этот ответ. Если другие ответы не будут опубликованы, это может быть полезно для других.

Смежные вопросы