MEF和抽象工厂

Dmi*_*gin 5 .net c# dependency-injection mef .net-4.5

更新:我应该尝试通过DI容器处理它还是这里的错误抽象级别?

我想使用MEF(.NET 4.5)实现抽象工厂.

它对我不起作用......

构图保持不变.由于以下错误,更改被拒绝:

该组合物产生单一组成误差.根本原因如下.查看CompositionException.Errors属性以获取更多详细信息.

1)没有找到符合约束条件的导出:

ContractName Mef3.Factory

RequiredTypeIdentity Mef3.Factory导致:无法在"Mef3.Program"部分设置导入'Mef3.Program._factory(ContractName ="Mef3.Factory")'.

元素:Mef3.Program._factory(ContractName ="Mef3.Factory") - > Mef3.Program

这是在MEF中做到这一点的正确方法吗?如何将id转发给Foo/Bar ctors?

代码:

class Program
{
    static void Main(string[] args)
    {
        var program = new Program();
        program.Run();
    }

    readonly CompositionContainer _container;

    public Program()
    {
        var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
        _container = new CompositionContainer(catalog);
        _container.ComposeParts(this);
    }

    [Import]
    public Factory _factory;

    public void Run()
    {
        var foo = _factory.GetInstance("foo", 123);
        Console.WriteLine(foo is Foo);
    }
}

[Export]
public class Factory
{
    private readonly ExportFactory<Foo> _fooFactory;
    private readonly ExportFactory<Bar> _barFactory;

    [ImportingConstructor]
    public Factory(ExportFactory<Foo> fooFactory, ExportFactory<Bar> barFactory)
    {
        _fooFactory = fooFactory;
        _barFactory = barFactory;
    }

    public Base GetInstance(string name, int id)
    {
        switch (name)
        {
            case "foo":
                return _fooFactory.CreateExport().Value;

            case "bar":
                return _barFactory.CreateExport().Value;
        }

        throw new ArgumentException();
    }
}

public class Foo : Base
{
    [ImportingConstructor]
    public Foo([Import("Id")] int id)
    {
    }
}

public class Bar : Base
{
    [ImportingConstructor]
    public Bar([Import("Id")] int id)
    {
    }
}

[InheritedExport]
public abstract class Base
{
}
Run Code Online (Sandbox Code Playgroud)

Wes*_*ard 1

该问题似乎是由 Foo 和 Bar 上的 [Import("Id")] 引起的。不存在合同名称为“Id”的导出。MEF 通常不允许您在运行时传入导入,您需要能够在组合时满足整个图,否则它将无法工作。如果您想使用 MEF 来完成此特定场景,您应该删除 Foo 和 Bar 上的 ImportingConstructor 并在 Base 类上添加 SetId 方法,并让您的工厂在调用 GetInstance 时调用它。