2008-11-05 14 views
1

Utilisation de MEF Je souhaite effectuer les opérations suivantes.MEF, création de l'arbre d'importation lorsqu'une branche est demandée

J'ai un shell WPF. Pour le shell, je veux importer à partir d'une autre DLL un UserControl qui est également une vue de mon triade MVP. La façon dont la triade MVP fonctionne, c'est que dans le présentateur, j'ai un constructeur qui prend à la fois IModel et IView et les câbler. Ainsi, pour que cela fonctionne, je dois MEF faire ce qui suit:

  1. Créer IView mise en œuvre
  2. Créer IModel mise en œuvre
  3. Créer Presenter et passer IModel et IView à son constructeur
  4. importation IView mise en œuvre dans mon shell quand il est affiché

Au lieu de ce qu'il fait, il crée seulement le type Exporter IView et le passe à la coquille, skipp essentiellement Les étapes 2 et 3 sont assez logiques, quand on y pense, mais comment puis-je dire au MEF de créer aussi toute la triade quand je demande un IView. Je n'ai pas besoin de référencer Presenter ni modéliser ailleurs dans mon fichier .dll Shell, le mettre en tant qu'importation n'est donc pas une option (et ce serait plutôt moche de toute façon :). J'utilise la dernière goutte de MEF (Preview 2 Refresh). Quelqu'un?

== == Mise à jour

J'ai trouvé une solution et je blogué à ce sujet ici:
Krzysztof Koźmic's blog - Creating tree of dependencies with MEF

Cependant, je serais plus heureux si quelqu'un est venu avec un meilleur solution. **

+0

Avez-vous mis [ImportingConstructor] sur le constructeur? –

+0

Oui, j'ai vérifié le lien que j'ai fourni, il y a une version simplifiée du code et ma solution. Cela fonctionne mais je me demande s'il y a une meilleure façon de le faire. –

Répondre

2

Vérifiez ma réponse ici.

http://codebetter.com/blogs/glenn.block/archive/2008/11/12/mvp-with-mef.aspx

EDIT: (Ajout du lien, pour éviter ne pas être marqué comme faible qualité/LOA)

1: using System.ComponentModel.Composition; 
    2: using System.Reflection; 
    3: using Microsoft.VisualStudio.TestTools.UnitTesting; 
    4: 
    5: namespace MVPwithMEF 
    6: { 
    7:  /// <summary> 
    8:  /// Summary description for MVPTriadFixture 
    9:  /// </summary> 
    10:  [TestClass] 
    11:  public class MVPTriadFixture 
    12:  { 
    13:   [TestMethod] 
    14:   public void MVPTriadShouldBeProperlyBuilt() 
    15:   { 
    16:    var catalog = new AttributedAssemblyPartCatalog(Assembly.GetExecutingAssembly()); 
    17:    var container = new CompositionContainer(catalog.CreateResolver()); 
    18:    var shell = container.GetExportedObject<Shell>(); 
    19:    Assert.IsNotNull(shell); 
    20:    Assert.IsNotNull(shell.Presenter); 
    21:    Assert.IsNotNull(shell.Presenter.View); 
    22:    Assert.IsNotNull(shell.Presenter.Model); 
    23:   } 
    24:  } 
    25: 
    26:  [Export] 
    27:  public class Shell 
    28:  { 
    29:   private IPresenter _presenter = null; 
    30:   
    31:   public IPresenter Presenter 
    32:   { 
    33:    get { return _presenter; } 
    34:   } 
    35: 
    36:   [ImportingConstructor] 
    37:   public Shell(IPresenter presenter) 
    38:   { 
    39:    _presenter = presenter; 
    40:   } 
    41:  } 
    42: 
    43:  public interface IModel 
    44:  { 
    45:  } 
    46: 
    47:  [Export(typeof(IModel))] 
    48:  public class Model : IModel 
    49:  { 
    50:   
    51:  } 
    52: 
    53:  public interface IView 
    54:  { 
    55:  } 
    56: 
    57:  [Export(typeof(IView))] 
    58:  public class View : IView 
    59:  { 
    60:  } 
    61: 
    62:  public interface IPresenter 
    63:  { 
    64:   IView View { get;} 
    65:   IModel Model { get; } 
    66:  } 
    67: 
    68:  [Export(typeof(IPresenter))] 
    69:  public class Presenter : IPresenter 
    70:  { 
    71: 
    72:   private IView _view; 
    73:   private IModel _model; 
    74: 
    75:   [ImportingConstructor] 
    76:   public Presenter(IView view, IModel model) 
    77:   { 
    78:    _view = view; 
    79:    _model = model; 
    80:   } 
    81: 
    82:   public IView View 
    83:   { 
    84:    get { return _view; } 
    85:   } 
    86: 
    87:   public IModel Model 
    88:   { 
    89:    get { return _model; } 
    90:   } 
    91: 
    92:  } 
    93: } 

Alors qu'est-ce qui se passe ici?

Shell est injecté avec Presenter. Presenter est injecté avec View et Model. Tout ici est singletons, mais n'a pas à être. La différence entre nos deux exemples est que le présentateur est injecté dans le shell plutôt que dans la vue. Si le présentateur est en train de créer la vue, vous ne pouvez pas simplement saisir la vue en premier (comme il le faisait), ou le présentateur ne sera pas créé. Eh bien, vous pouvez le faire, mais vous finissez par le pirater en morceaux. Cleaner consiste simplement à injecter le Presenter et à l'exposer à un IView. Nous l'avons fait dans Prism et cela a très bien fonctionné.

+0

(+1) alors que cela semble répondre à la question, il est considéré comme un message de mauvaise qualité car la réponse est juste un lien. C'est beaucoup mieux si, en plus du lien, une description ou un résumé du problème et la solution proposée dans le lien étaient en ordre. Je pensais que je laisserais une note ici car elle * était marquée * comme de mauvaise qualité. – Arun

+0

Que faire si le lien est brisé? –

1

La façon dont vous avez souligné dans votre article de blog est la manière parfaitement valide d'utiliser MEF. Il s'agit d'une composition imbriquée, et lors de la conception, il est toujours bon de garder à l'esprit que Container est le décideur, donc en tant que fournisseur plug-in/extendeur, vous vous concentrerez sur vos services que vous «exportez». ne vous inquiétez pas de ce que vous avez besoin d'être entretenu, ou "importer" (ce point a quelques problèmes dans la dernière baisse, mais j'entends assez bon pour être optimiste à ce sujet). Par conséquent, dans une composition imbriquée, vous aurez peut-être besoin de services externes, mais vous pouvez également en fournir à l'heure actuelle. Quand vous faites un montage, tout est branché.

J'ai un blog contenant 2 exemples illustrant cette façon de penser:

http://www.sidarok.com/web/blog/content/2008/09/26/what-is-this-managed-extensibility-framework-thing-all-about.html

En outre, de laisser tomber les dll et regarder les types qu'il contient, vous pouvez utiliser DirectoryPartCatalog regarder ce dossier.

Vous devrez également surveiller les scénarios où plusieurs exportations sont effectuées pour le même contrat et déterminer la bonne à partir des métadonnées fournies.