0

FooControllerというクラスがあり、その中にIBar(インターフェイス)タイプのBarというプロパティがあるとします。MEFを介してBarを初期化する必要があります。ただし、MEFは、アプリケーションの期間中にIBarタイプのインスタンスを1つだけ作成し(複数の要求のために初期化するために複数の呼び出しがあるにもかかわらず)、すべての要求で同時に使用できるようにする必要があります。IBarの実装はスレッドセーフであると見なすことができることに注意してください。

すなわち

public interface IBar
{
    string Method();
}

[Export(typeof(IBar))]
public class MyBar: IBar
{
    public string dateTimeCreated;

    public MyBar()
    {
        System.Threading.Thread.Sleep(1000);
        dateTimeCreated = DateTime.Now.ToLongTimeString() + " ";
    }

    public string Method()
    {
        return dateTimeCreated;
    }
}

public class FooController : ApiController
{
    [Import(typeof(IBar), RequiredCreationPolicy = CreationPolicy.Shared)]
    public IBar Bar { get; set; }

    public FooController()
    {
        //Assume CompositionContainer.ComposeParts call here
    }

    public string Get()
    {            
        return Bar.Method();
    }
}

問題は、FooControllerでGet()を呼び出すたびに、返される時間の値が変わることです。これは、MyBarオブジェクトが呼び出しごとに再インスタンス化されていることを意味します。基本的に同じ値を返す必要があります。つまり、複数のリクエストがあるにもかかわらず、アプリケーションでIBarのインスタンスを1つだけ作成するようにMEFに指示する必要があります。

前もって感謝します。

4

2 に答える 2

1

エクスポートでPartCreationPolicy属性を指定する必要があります。MyBarこのような:

[Export(typeof(IBar))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class MyBar : IBar
{
    // ...
}

これは、インポート時に作成ポリシーを指定する必要がないことも意味します。

[Import]
public IBar Bar { get; set; }
于 2013-01-27T21:13:45.350 に答える
0

MEF の ASP.NET MVC 統合は、HTTP 要求ごとに を単一のインスタンスとして解釈CreationPolicy.Anyします。HTTP リクエスト間で属性を共有するには、パーツに属性CreationPolicy.Sharedを適用する必要があります。ApplicationShared

アップデート:

はアセンブリApplicationSharedAttributeにあります。System.ComponentModel.Composition.Web.Mvc残念ながら、これは Framework 4.5 では配布されていません。これは、 libフォルダーのUsing MEF with ASP.NET MVC 3 サンプル コードの例にあります。欠点は、最新のものではなく、そのサンプルで見つかった構成アセンブリを参照する必要があることです。

それをしたくない場合は、次の非常に単純なアプローチから始めます。

  1. クラスに a をプロパティとして追加CompositionContainerします。MvcApplicationpublic
  2. MvcApplicationコンストラクターでコンテナーを作成し、いくつかのカタログを追加します。
  3. コントローラーで、HttpContext からアプリケーションを取得し、.// のいずれかのGetExportメソッドGetExportedValueGetExportedValues使用しCompositionContainerます。ComposePartsコンテナを呼び出す必要はありません。

より精巧なアプローチは他にもたくさんありますが、これで始めることができます。

于 2013-01-31T23:40:04.407 に答える