2009-05-05 11 views
2

MEFエクスポートに共有パート作成ポリシーを使用しようとしています。しかし、私が考えていたように動作するようには見えません。私はアプリケーションで2回作曲を行い、毎回オブジェクトの新しいコピーを取得します。オブジェクトインスタンシエーションにインスタンスカウンタを追加することでこれを証明しました。MEF作成ポリシー

static int instCount = 0; 

    public FakeAutocompleteRepository() 
    { 
     instCount++; 
     ... 
    } 

すべてをデバッグで実行しています。実際、私は輸出セクションが

[PartCreationPolicy(CreationPolicy.Shared)] 
[Export(typeof(IAutocompleteRepository))] 
[ExportMetadata("IsTesting", "True")] 
class FakeAutocompleteRepository : IAutocompleteRepository 
{ ... } 

が含まれていinstCount = 2でFakeAutocompleteRepositoryの新しいコピーを取得構図を行う二回目はsubsiquent要求に対して同じインスタンスを取得するが、いくつかのトリックですか?私が作曲中に何かしている場合、これは私がやっていることです。

var catalog = new AggregateCatalog(); 
       catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly())); 
       catalog.Catalogs.Add(new DirectoryCatalog(".")); 
       var container = new CompositionContainer(catalog); 
       var batch = new CompositionBatch(); 
       batch.AddPart(this); 
       container.Compose(batch); 


       if (null != ConfigurationSettings.AppSettings["IsTesting"] && bool.Parse(ConfigurationSettings.AppSettings["IsTesting"])) 
        repository = container.GetExports<IAutocompleteRepository>().Where(expDef => expDef.Metadata.Keys.Contains("IsTesting")).Single().GetExportedObject(); 

基本的に私はテスト中に特定の曲を強制しようとしています。これらの作品を単体テストするための良いアイデアがあるなら、私はすべて耳にします。

答えて

3

あなたのコードに複数の部分が作成されるようなものは特にありません。コンポジションごとに異なるコンテナを作成していますか?そうであれば、それは別々のインスタンスを取得している理由です。

構成とユニットテストを一般的にどのように組み合わせるかについては、このhereの議論があります。

+0

私はまったく新しいコンテナを作成しています。アクティブなコンテナを照会する方法はありますか、またはアプリケーションごとにインスタンスを作成する必要がありますか? – stimms

+0

アクティブなコンテナを照会する方法はありません。私は、あなたがすべきことについてアドバイスをするために、あなたのアプリケーションについてもっと理解しなければならないでしょう。複数のコンポジションは何ですか? –

+0

できることホストからコンテナをエクスポートし、使用するたびにインポートします。私はそれをしていないが、私はMefShapesのゲームの例でそれを見たと思う... –

2

私がユニットテストのために行ったことは、構成を避けることでした。たとえば、(私はここではWPFとMVVMを使用しています)、あなたは、このビューモデルをテストしたいとしましょう:

[Export("/MyViewModel")] 
public class MyViewModel 
{ 
    [ImportingConstructor] 
    public MyViewModel(
     [Import("/Services/LoggingService")] ILoggingService l) 
    { 
     logger = l; 
    } 

    private ILoggingService logger { get; set; } 

    /* ... */ 
} 

私は、本格的なログサービス私はユニットテストを行うたびにインスタンス化する必要はありませんだから、私はILoggingServiceを実装しているMockLoggingServiceクラスを持っているだけで、すべてのログメッセージを呑み込む(または気にするなら、適切なメッセージが生成されていることを確認する)。それでは、私のユニットテストでこれを行うことができます:

MyViewModel target = new MyViewModel(new MockLoggingService());