2009-06-03 5 views
11

Attualmente la mia applicazione WPF importa una parte come questoCreazione di più istanze di parti importate MEF

[Import(typeof(ILedPanel)] 
public ILedPanel Panel { get; set; } 

Ma questo dà ma un unico intance della classe che implementa ILedPanel. Quello che voglio veramente fare è avere la possibilità di creare il maggior numero di istanze di cui ho bisogno. Si noti che esiste una sola esportazione per ILedPanel incluso con il software in qualsiasi momento.

(Se uso un'importazione con la lista che mi dà un'istanza per ogni classe che implementa ILedPanel)

Qualche suggerimento?

+0

Non sono sicuro che sia un buon modo, ma sono andato semplicemente con Activator.CreateInstance (Panel.GetType()); – TimothyP

risposta

9

Non v'è "costruito in" supporto per questo in MEF oggi, ma prima di ritornare al Service Locator, si potrebbe trovare qualche ispirazione qui: http://blogs.msdn.com/nblumhardt/archive/2008/12/27/container-managed-application-design-prelude-where-does-the-container-belong.aspx

L'idea essenziale è che si 'importa' il contenitore nel componente che deve eseguire l'istanza dinamica.

Un ulteriore supporto diretto per questo scenario è qualcosa che stiamo esplorando.

Nick

UPDATE: MEF ha ora il supporto sperimentale per questo. Vedere this blog post per ulteriori informazioni.

+0

beh sapevo che avresti trovato la domanda non avrei detto nulla .... :) –

+1

AGGIORNAMENTO: questa funzione è stata introdotta in MEF "Anteprima 7" come PartCreator - consulta il wiki MEF per informazioni (http://mef.codeplex.com/Wiki/View.aspx?title=PartCreator&referringTitle=Home) –

+1

Ma solo per Silverlight sembrerebbe – TimothyP

2

Penso che vuoi dire che vuoi usare MEF in questa istanza come un localizzatore di servizi piuttosto che un contenitore per l'iniezione di dipendenza. Prova a guardare gli esempi per ValueResolver

10

io non sono sicuro se questo è ciò che Nicolas si riferisce, ma è possibile importare una classe di fabbrica, piuttosto che una classe di esempio, in questo modo:

[Import(typeof(ILedPanelFactory)] 
public ILedPanelFactory PanelFactory { get; set; } 

... e poi più avanti nel codice ...

ILedPanel panel = PanelFactory.BuildPanel(); 
3

Guardando il campione forme di gioco che viene fornito con MEF, v'è la classe ShapeFactory:

[Export] 
public class ShapeFactory 
{ 
    private readonly Random random = new Random((int)DateTime.Now.Ticks); 

    [Import] 
    private ICompositionService CompositionService { get; set; } 

    public IShape GetRandomShape() 
    { 
     var shapeRetriever = new ShapeRetriever(); 

     CompositionService.SatisfyImports(shapeRetriever); 

     int randomIndex = random.Next(shapeRetriever.PossibleShapes.Length); 

     return shapeRetriever.PossibleShapes[randomIndex].GetExportedObject(); 
    } 

    private class ShapeRetriever 
    { 
     [ImportMany(RequiredCreationPolicy = CreationPolicy.NonShared)] 
     public Export<IShape, IShapeMetadata>[] PossibleShapes { get; set; } 
    } 
} 

Che dimostra la creazione di istanze di forme casuali "su richiesta" ... Penso che nel tuo scenario potresti fare qualcosa di simile senza la selezione di un'implementazione casuale, poiché suggerisci che ci sarebbe solo un'implementazione di ILedPanel registrata.

5

A meno che non abbia frainteso la domanda, sembra che sarebbe stata risolta usando semplicemente CreationPolicy.NonShared.

Ciò presuppone che il codice che dichiara il Pannello esista ovunque si desideri un pannello. Otterrai una nuova istanza di ILedPanel in ogni istanza di ogni classe che ha questa dichiarazione (l'importazione).

+0

È vero. Ma esiste solo una classe che implementa ILedPanel con qualsiasi distribuzione del software. Quindi questa è una singola istanza ... ovviamente non è pulita – TimothyP

8

Tutte le altre risposte sono piuttosto vecchie, quindi non menzionano una funzionalità relativamente nuova in MEF denominata ExportFactory.Questa classe generica consente di importare ExportFactory<ILedPanel> e creare il maggior numero di casi che vuoi ogni volta che ne avete bisogno, in modo che il codice sarebbe simile a questa:

[Import(typeof(ILedPanel)] 
public ExportFactory<ILedPanel> PanelFactory { get; set; } 

public ILedPanel CreateNewLedPanelInstance() 
{ 
    return PanelFactory.CreateExport().Value; 
} 

Questo metodo soddisfa anche tutte le importazioni che hanno creato parte ha. Puoi leggere ulteriori informazioni sull'uso della classe ExportFactoryhere.

+0

È fantastico, grazie per l'aggiornamento! – TimothyP