2009-06-03 4 views
11

Actuellement MEF mon application WPF importe un cadre comme celui-ciplusieurs instances de pièces importées

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

Mais cela donne ma seule une intance de la classe qui implémente ILedPanel. Ce que je veux vraiment faire, c'est avoir la possibilité de créer autant d'instances dont j'ai besoin . S'il vous plaît noter qu'il n'y a qu'un seul Export pour ILedPanel inclus avec le logiciel à un moment donné.

(Si j'utilise une importation avec la liste qui me donne une instance pour chaque classe implémentant ILedPanel)

Toutes les suggestions?

+0

Je ne suis pas sûr que ce soit un bon moyen mais je suis simplement allé avec Activator.CreateInstance (Panel.GetType()); – TimothyP

Répondre

9

Il n'y a pas « construit en » soutien pour cela dans MEF aujourd'hui, mais avant de revenir au service de localisation, vous pourriez trouver un peu d'inspiration ici: http://blogs.msdn.com/nblumhardt/archive/2008/12/27/container-managed-application-design-prelude-where-does-the-container-belong.aspx

L'idée essentielle est que vous 'importe' le conteneur dans le composant qui doit faire l'instanciation dynamique.

Plus de support direct pour ce scénario est quelque chose que nous explorons.

Nick

MISE À JOUR: MEF a maintenant un support expérimental pour cela. Voir this blog post pour plus d'informations.

+0

bien si je savais que vous trouveriez la question que je n'aurais rien dit .... :) –

+1

MISE À JOUR: cette fonctionnalité a fait son chemin dans MEF "Preview 7" en tant que PartCreator - voir le wiki MEF pour plus d'informations (http://mef.codeplex.com/Wiki/View.aspx?title=PartCreator&referringTitle=Home) –

+1

Mais seulement pour Silverlight, il semblerait – TimothyP

2

je pense que vous voulez dire que vous voulez utiliser dans ce cas MEF comme un localisateur de service plutôt qu'un conteneur d'injection de dépendance. Essayez de regarder des exemples pour ValueResolver

10

Je ne suis pas sûr que ce soit ce que Nicolas fait référence, mais vous pouvez importer une classe d'usine plutôt que d'une classe d'instance, comme ceci:

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

... et puis plus tard dans votre code ...

ILedPanel panel = PanelFactory.BuildPanel(); 
3

regardant l'échantillon de jeu de formes qui vient avec MEF, il y a 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; } 
    } 
} 

Ce qui démontre la création d'instances de formes aléatoires "à la demande" ... Je pense que dans votre scénario vous pourriez faire quelque chose de similaire sans la sélection d'une implémentation aléatoire, comme vous le suggérez il n'y aurait qu'une implémentation de ILedPanel.

5

À moins que je comprends mal la question, on dirait qu'il serait résolu en utilisant simplement un CreationPolicy.NonShared.

Cela suppose que le code déclarant le panneau existe partout où vous voulez un panneau. Vous obtiendriez une nouvelle instance de ILedPanel dans chaque instance de chaque classe qui avait cette déclaration (l'importation).

+0

C'est vrai. Mais il n'y a qu'une classe qui implémente ILedPanel avec n'importe quelle distribution du logiciel. Donc, c'est une instance unique ... ce n'est pas propre bien sûr – TimothyP

8

Toutes les autres réponses sont assez vieux, donc ils ne mentionnent pas une caractéristique relativement nouveau dans MEF appelé ExportFactory.Cette classe générique vous permet d'importer ExportFactory<ILedPanel> et créer autant d'instances que vous le souhaitez à chaque fois que vous en avez besoin, de sorte que votre code ressemblerait à ceci:

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

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

Cette méthode satisfait également toutes les importations qui ont créé une partie a. Vous pouvez en savoir plus sur l'utilisation de la ExportFactory classe here.

+0

C'est génial, merci pour la mise à jour! – TimothyP