4

私は MEF に比較的慣れていないため、機能を完全には理解していません。Unity の InjectionMember に似たものを達成しようとしています。

MEF パーツをインポートするクラスがあるとします。簡単にするために、エクスポートされた部分の例として次のクラスを取り上げます。

[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class Logger {

    public string Category {
        get;
        set;
    }

    public void Write(string text) {
    }

}

public class MyViewModel {

    [Import]
    public Logger Log {
        get;
        set;
    }

}

今、私が理解しようとしているのは、インポート時に Category プロパティの値を指定できるかどうかです。何かのようなもの:

public class MyViewModel {

    [MyImportAttribute(Category="MyCategory")]
    public Logger Log {
        get;
        set;
    }

}

public class MyOtherViewModel {

    [MyImportAttribute(Category="MyOtherCategory")]
    public Logger Log {
        get;
        set;
    }

}

とりあえずやっていることは IPartImportsSatisfiedNotification の実装とコードでの Category の設定です。しかし、明らかに、すべてを 1 か所にきちんとまとめておきたいと思います。

4

2 に答える 2

6

MEF プログラミング ガイドエクスポートとメタデータに関するセクションを参照してください。ExportMetadata属性を使用するか、独自のカスタム エクスポート属性を定義して、エクスポートされたパーツにメタデータを追加する方法を示します。

ILoggerMetadata次に、次のようなインターフェイスを定義できます。

public interface ILoggerMetadata
{
    string Catagory { get; }
}

を実行し、次ImportManyIEnumerable<Lazy<ILogger,ILoggerMetadata>>ようなコードで必要なものを選択します。

private ILogger fooLogger;

[ImportMany]
public IEnumerable<Lazy<ILogger,ILoggerMetadata>> Loggers
{
    set
    {
        this.fooLogger = value.First(x => x.Metadata.Catagory == "foo").Value;
    }
}

メタデータの制約を import 属性に直接配置した方がよいという意見には同意しますが、これは MEF ですぐに使用することはできません。(これを行うために MEF を拡張することは可能かもしれません。)

もう 1 つの方法は、 からIFooLoggerインターフェイスを派生させILogger、それをインポートとエクスポートで使用することです。これは単純で、インポートに制約を入れるのと本質的に同じ効果があります。ただし、複数のメタデータ属性や可能な値が多数ある場合、このアプローチは機能しません。

編集:あなたの質問を微妙に誤解していました。インポートされたオブジェクトを追加のパラメーターで構成するのではなく、インポートを制限することだと思いました。

Kathleen Dollard によるこの最近の投稿は、同じ問題に関するものだと思います。また、コンポーネント関係に関するこの投稿Func<X,Y>では、Nicholas Blumhardt が(またはFunc<ILogger,string>あなたの場合は)の注入などの「パラメーター化」関係をモデル化しています。

[Export(typeof(Func<ILogger,string>))]メソッドに属性を直接配置することで、MEF でも同じことができます。または、あいまいさの少ないコントラクトが必要な場合は、次のようなILoggerFactoryインターフェイスとインポート/エクスポートを定義できます。

public ILoggerFactory
{
    ILogger Create(string category);
}

ただし、最終的には、コードでファクトリを呼び出す必要があります。

于 2010-04-15T09:35:19.750 に答える
3

MEFをさらに掘り下げた後、これを宣言的に行う方法はないようです。独自のエクスポート属性を派生させることはできますが、意味のある方法でインポート属性を派生させるメカニズムはないようです。

しかし、IPartImportsSatisfiedNotification を実装する代わりに、私ができること (今では明らかなようです) は、セッターでカテゴリを設定することです。自動プロパティを放棄する必要がありますが、それが人生です。

public class MyViewModel {

    private Logger log;

    [Import]
    public Logger Log {
        get { return log; }
        set {
            log = value;
            log.Category = "MyCategory";
        }
    }

}
于 2010-04-15T14:09:20.883 に答える