2009-05-05 14 views
2

Ich versuche, die Richtlinie für die gemeinsame Teileerstellung für einen MEF-Export zu verwenden. Es scheint jedoch nicht so zu funktionieren, wie ich es mir vorgestellt habe. Ich mache die Komposition zweimal in meiner Bewerbung und bekomme jedes Mal eine neue Kopie des Objekts. Ich habe dies durch Hinzufügen eines Instanzzählers zur Objekt-InstanziierungMEF-Erstellungsrichtlinie

static int instCount = 0; 

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

getestet und alles im Debug ausgeführt. Tatsächlich ist das zweite Mal, dass ich eine Zusammensetzung, bekomme ich eine neue Kopie des FakeAutocompleteRepository mit instCount = 2. Dem Export Abschnitt enthält

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

Gibt es einen Trick, um die gleiche Instanz für subsiquent Anfragen zu bekommen? Falls es etwas, das ich während der Komposition tue dies, wie ich tue, dass

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(); 

Grundsätzlich während des Tests mit einer spezifischen Zusammensetzung zu zwingen, ich versuche. Wenn Sie eine bessere Idee haben, diese Kompositionen zu testen, bin ich ganz Ohr.

Antwort

3

Ich sehe nichts speziell in Ihrem Code, der mehr als einen Teil Ihres Teils verursachen würde. Erstellen Sie für jede Komposition einen anderen Container? Wenn Sie das sind, erhalten Sie deshalb getrennte Instanzen.

Soweit wie Zusammensetzung und Unit-Tests im Allgemeinen zu kombinieren, gibt es einige Diskussion dieser here.

+0

Ich erstelle jedes Mal einen neuen Container. Gibt es eine Möglichkeit, aktive Container abzufragen, oder sollte man irgendwo eine Anwendungsinstanz erstellen? – stimms

+0

Es gibt keine Möglichkeit, aktive Container abzufragen. Ich müsste mehr über Ihre Bewerbung verstehen, um Sie zu beraten, was Sie tun sollten. Wofür sind die vielfältigen Kompositionen? –

+0

Sie können Ihren Container von Ihrem Host exportieren und ihn jedes Mal importieren, wenn Sie ihn verwenden möchten. Ich habe das noch nicht gemacht, aber ich denke, ich habe es im Spielbeispiel von MefShapes gesehen ... –

2

Was ich für Unit-Tests getan habe, war die Zusammensetzung zu vermeiden. Zum Beispiel (ich bin mit WPF und MVVM hier), lassen Sie uns sagen, dass Sie diese Ansichtsmodell testen wollen:

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

    private ILoggingService logger { get; set; } 

    /* ... */ 
} 

Ich will nicht die ausgewachsenen Protokollierungsdienst jedes Mal, wenn ich einen Komponententest tun instanziiert, Also habe ich eine MockLoggingService-Klasse, die ILoggingService implementiert und es schluckt nur alle Protokollnachrichten (oder prüft, ob die richtigen Nachrichten generiert werden, falls Sie sich interessieren). Dann kann ich das in meinem Komponententest tun:

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