Составление экспортируемого значения с помощью MEF 2

В MEF 1 можно было скомпоновать существующий объект в контейнер с помощью метода ComposeExportedValue(...) (container.ComposeExportedValue...). Как это можно сделать с помощью Microsoft.Composition (MEF 2)? Я не могу найти метод для этой цели.


person user31705    schedule 10.02.2016    source источник


Ответы (2)


У меня будет шанс на это. Конечно, я сам только около недели изучаю MEF 2 после некоторого ограниченного знакомства с MEF 1. Поэтому, пожалуйста, примите это во внимание при следующем ответе, поскольку он может быть совершенно неправильным. Кроме того, я нашел документацию очень плохой и устаревшей, поэтому до сих пор это была тяжелая битва во всех отношениях.

В своем решении я использовал ExportDescriptorProvider и расширил его до InstanceExportDescriptorProvider, как показано в следующем коде.

(Обратите внимание, что это следует рассматривать как доказательство концепции, а не окончательный код!)

public class InstanceExportDescriptorProvider : ExportDescriptorProvider
{
    readonly object instance;

    public InstanceExportDescriptorProvider( object instance )
    {
        this.instance = instance;
    }

    public override IEnumerable<ExportDescriptorPromise> GetExportDescriptors( CompositionContract contract, DependencyAccessor descriptorAccessor )
    {
        if ( contract.ContractType.IsInstanceOfType( instance ) )
        {
            yield return new ExportDescriptorPromise( contract, contract.ContractType.FullName, true, NoDependencies, dependencies => ExportDescriptor.Create( ( context, operation ) => instance, NoMetadata ) );
        }
    }
}

Вспомогательный тест (с использованием xUnit 2.0 в сочетании с AutoFixture), чтобы показать, как это будет использоваться, выглядит следующим образом:

[Theory, AutoData]
public void VerifyInstanceExport( Assembly[] assemblies )
{
    using ( var container = new ContainerConfiguration()
        .WithProvider( new InstanceExportDescriptorProvider( assemblies ) )
        .CreateContainer() )
    {
        var composed = container.GetExport<Assembly[]>();
        Assert.Equal( assemblies, composed );
    }
}

В моем случае я хочу иметь доступ к сборкам, переданным в ContainerConfiguration (не видно/не проверено в приведенном выше примере), поэтому я тестирую сборки.

Надеюсь, этого будет достаточно, чтобы вы продолжили свой путь. Или каким-то образом, в любом случае.

person Mike-E    schedule 03.03.2016
comment
Вау, это совсем некрасиво. Я подозреваю, что вы правы в том, что WithProvider - единственный способ сделать это. К счастью, кажется, что это универсальное средство, позволяющее заполнить любые дыры в API. Существует проблема с github для составления экспортированных значений из существующего экземпляра: github.com/dotnet/corefx/issues. /11856 - person David Beavon; 18.08.2017

https://mef.codeplex.com/ указывает, что

System.Composition.*_ — это облегченная версия MEF, оптимизированная для сценариев статической композиции и обеспечивающая более быструю композицию.

И насколько я знаю из своего опыта, System.Composition не поддерживает динамическую композицию. Если вам нужны такие возможности, вы должны использовать стандартный MEF (System.ComponentModel.Composition.*).

person Usein Mambediiev    schedule 23.02.2016