2012-01-25 7 views
5

Sto utilizzando la gerarchia di container per controllare le parti IDisposable a vita. Il contenitore secondario è collegato al catalogo filtrato che contiene parti non condivise. Ecco un frammento di codice:Gerarchia contenitore MEF e GetExports <T>

[Export(typeof(ITest)), PartCreationPolicy(CreationPolicy.NonShared)] 
class Test : ITest, IDisposable 
{ 
    public void Dispose() {} 
} 

public interface ITest {} 

class Program 
{ 
    static void Main() 
    { 
    // parent container to hold shared disposable parts 
    var cat = new AssemblyCatalog(typeof(Program).Assembly); 
    var parent = new CompositionContainer(cat); 

    // child container to hold non-shared disposable parts 
    var nsCat = CreateNonSharedPartCatalog(cat); 
    var child = new CompositionContainer(nsCat, parent); 

    // no cardinality mismatch exception: exactly one export found 
    var exp = child.GetExport<ITest>(); 

    // lazy exports: count == 2 -- why? 
    var exports = child.GetExports<ITest>(); 
    Console.WriteLine("Exports count = {0}", exports.Count()); 
    } 

    static ComposablePartCatalog 
    CreateNonSharedPartCatalog(ComposablePartCatalog cat) 
    { 
    return new FilteredCatalog(cat, 
     def => def.Metadata.ContainsKey(
     CompositionConstants.PartCreationPolicyMetadataName) && 
     ((CreationPolicy)def.Metadata[ 
     CompositionConstants.PartCreationPolicyMetadataName]) == 
      CreationPolicy.NonShared); 
    } 
} 

(classe FilteredCatalog è la stessa che menzionato nella documentazione MEF).

GetExport non lancia un'eccezione di disallineamento di cardinalità che indica che non vi è ambiguità (viene trovata esattamente un'esportazione). Ma con mia sorpresa, GetExports() restituisce 2 esportazioni pigre invece di 1.

I un bug o questo comportamento è di progettazione? Come posso configurare il contenitore figlio in modo che GetExports restituisca un'esportazione in questo esempio?

+0

c'è qualcosa che importa 'ITest'? –

+0

No, ho pubblicato lo snippet completo qui. Solo le usanze e il codice della classe FilteredCatalog sono stati rimossi. – yallie

risposta

2

questa è una limitazione nota delle gerarchie di contenitori in MEF utilizzando cataloghi filtrati. Credo (ma non posso confermare questo momento) che l'impostazione della sorgente di importazione:

[ImportMany(Source=ImportSource.Local)] 
public IEnumerable<ITest> Tests { get; set; } 

dovrebbe dare il comportamento desiderato (ma solo in MEF2/.NET 4.5 Developer Preview).

Spero che questo aiuti!

+0

Grazie per la risposta! Questa funzionalità è disponibile in MEF2 Preview5 pubblicata su CodePlex? – yallie

+0

Questa funzione funziona come descritto ed è effettivamente disponibile in MEF2 Preview5 pubblicata su CodePlex. Tuttavia, impostando Source su ImportSource.Local verranno estratte solo le parti dal contenitore secondario, quindi le parti non condivise non potrebbero essere importate in questo modo. Quello che stavo cercando di fare è ottenere tutte le parti esportate (sia condivise che non condivise), ma senza duplicati. – yallie

+0

Ah - Vedo il problema, mi dispiace. Anche in 4.5 DP abbiamo 'CompositionScopeDefinition' che ha una migliore possibilità di gestire questo caso - vedi: http://blogs.msdn.com/b/bclteam/archive/2011/12/19/sharing-with-compositionscopedefinition-in -mef2-alok.aspx –