5

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

我想使用 MEF (.NET 4.5) 实现 ABSTRACT FACTORY。

它对我不起作用...

组成保持不变。由于以下错误,更改被拒绝:

合成产生了一个单一的合成错误。下面提供了根本原因。查看 CompositionException.Errors 属性以获取更多详细信息。

1) 未找到与约束匹配的导出:

合同名称 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
{
}
4

1 回答 1

1

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

于 2012-09-11T02:50:59.357 回答