5

更新: DI コンテナーで処理する必要がありますか、それとも抽象化レベルが間違っていますか?

MEF (.NET 4.5) を使用して ABSTRACT FACTORY を実装したいと考えています。

それは私にはうまくいきません...

構成は相変わらず。次のエラーのため、変更は拒否されました:

構成で 1 つの構成エラーが発生しました。根本的な原因を以下に示します。詳細については、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
{
}
4

1 に答える 1

1

この問題は、Foo と Bar の [Import("Id")] が原因のようです。契約名が「Id」のエクスポートはありません。一般に、MEF では、実行時にインポートを渡すことができません。構成時にグラフ全体を満たすことができる必要があります。そうしないと、機能しません。この特定のシナリオを実現するために MEF を使用する場合は、Foo と Bar の ImportingConstructor を削除し、Base クラスに SetId メソッドを追加して、GetInstance を呼び出すときにファクトリにそれを呼び出させる必要があります。

于 2012-09-11T02:50:59.357 に答える