0

Funqおよびおそらく他のほとんどの IoC コンテナーでは、これを行うだけでタイプを構成できます

container.Register<ISomeThing>(c => new SomeThing());

MEF をすばやく拡張 (または既存の MEF 機能を使用) して、属性を使用せずに同じことを行うにはどうすればよいでしょうか。

これが私ができると思った方法です:

var container = new CompositionContainer();
var batch = new CompositionBatch();
batch.AddExport<ISomeThing>(() => new SomeThing());
batch.AddExportedValue(batch);
container.Compose(batch);

この拡張メソッドを使用すると、次のようになりCompositionBatchます。

public static ComposablePart AddExport<TKey>(this CompositionBatch batch, Func<object> func)
{
    var typeString = typeof(TKey).ToString();
    return batch.AddExport(
        new Export(
            new ExportDefinition(
                typeString, 
                new Dictionary<string, object>() { { "ExportTypeIdentity", typeString } }),
            func));

}

私が後で行う場合:

var a = container.GetExport<ISomeThing>().Value;
var b = container.GetExport<ISomeThing>().Value;

どちらのインスタンスも同じです。それらを異なるインスタンスに強制 (構成) するにはどうすればよいですか?

これがうまくいかない場合、MEF でこれを行うにはどうすればよいですか?

4

4 に答える 4

1

属性を使用したくない場合は、このトリックを使用できます(Mark Seemannのブログ投稿に基づく)。

まず、次のようなジェネリッククラスを作成します。

[PartCreationPolicy(CreationPolicy.NonShared)]
public class MefAdapter<T> where T : new()
{
    private readonly T export;

    public MefAdapter()
    {
        this.export = new T();
    }

    [Export]
    public virtual T Export
    {
        get { return this.export; }
    }
}

これで、次のように、コンテナに必要なクラスを登録できます。

var registeredTypesCatalog = new TypeCatalog(
    typeof(MefAdapter<Foo>),
    typeof(MefAdapter<Bar>), 
    ...);
var container = new CompositionContainer(catalog);

または、 ExportProviderから派生した独自のエクスポートプロバイダーを実装することもできます。これにより、Funqの作業方法をほぼ複製できます。

var provider = new FunqyExportProvider();
provider.Register<IFoo>(context => new Foo());
var container = new CompositionContainer(provider);
于 2011-09-09T13:58:28.057 に答える
1

重要なのは、デリゲートをコンテナに追加することだと思います。例:

container.AddExportedValue<Func<ISomething>>(() => new Something());

そうすれば、デリゲートを取得して実行できます。

var factory = container.GetExport<Func<ISomething>>();
ISomething something = factory();

もちろん、MEF(Silverlight)はネイティブExportFactory<T>(およびExportFactory<T,TMetadata>インポートの呼び出しごとに新しいインスタンスの作成をサポートするタイプ)を提供します。GlenBlockのExportFactory for .NET 4.0(デスクトップ)ライブラリをダウンロードすることで、これのサポートを追加できます。

于 2011-09-09T12:08:30.803 に答える
0

どちらのインスタンスも同じです。それらを異なるインスタンスに強制 (構成) するにはどうすればよいですか?

SomeThing次のようにクラスをマークするだけです。

[Export(typeof(ISomeThing)]
[PartCreationPolicy(CreationPolicy.NonShared]
public class SomeThing : ISomeThing
{
   ...
}

そして、どこにインポートしても異なるインスタンスが得られますISomeThing

または、インポートに必要な作成ポリシーを設定することもできます。

[Export(typeof(IFoo))]
public class Foo : IFoo
{
   [Import(typeof(ISomeThing), 
       RequiredCreationPolicy = CreationPolicy.NonShared)]
   public ISomething SomeThing { private get; set; }

}
于 2011-09-09T13:44:20.997 に答える
0

Matthew Abbott の回答にリンクされている Glen Block の Skydrive ディレクトリで、シンプルで軽量に見えるものを見つけました: A FuncCatalog. ここからダウンロードしてください: FuncCatalogExtension

そのプロジェクトのいくつかの小さなクラスを使用して、これを実行できるようになりました。

var funcCatalog = new FuncCatalog();
funcCatalog.AddPart<ISomeThing>(ep => new SomeThing());
var container = new CompositionContainer(funcCatalog);
var batch = new CompositionBatch();
batch.AddExportedObject<ExportProvider>(container);
container.Compose(batch);

var a = container.GetExportedObject<ISomeThing>();
var b = container.GetExportedObject<ISomeThing>();
于 2011-09-09T13:46:48.640 に答える