2011-05-19 4 views
5

je la configuration suivante:Prism: EventAggregator et MEF - 2 cas différents de EventAggregator

  • Un split application Silverlight sur xaps/modules
  • J'utilise MEF comme cadre DI pour se connecter différentes parties de ma demande.

  • J'ai 2 régions:

  • un (celui de gauche) est peuplé de une vue de la liste (par exemple clients)

  • One (la droite) est peuplé de une vue contenant un tabcontrol avec une région que j'ai rempli (selon auquel le client est sélectionné) avec une autre vue contenant un contrôle de tabulation avec une région.

    Le résultat du côté droit: enter image description here

pour alimenter le premier niveau tabcontrol Je suis à l'écoute du « événement changé client » - (ce qui fonctionne très bien) et quand je reçois recevoir l'événement I alimenter la zone onglet de premier niveau avec vue:

Dim lReg As IRegion = Me.mRegionManager.Regions("FirstLevelTabReqion") 
    Dim lViewID As String = CommonDefinitions.Constants.BuildFirstLevelViewName(lUniqueID) 
    Dim lFirstLevelView FirstLevelView = TryCast(lReg.GetView(lRqViewID), FirstLevelView) 
    If lFirstLevelView Is Nothing Then  
     lFirstLevelView = New FirstLevelView() 
     Dim lRegMan1 As IRegionManager = lReg.Add(lFirstLevelView, lViewID, True) 
     lFirstLevelView.SetRegionManager(lRegMan1) 
     ... 
    End If 

note: Lors de la création du FirstLevelView je dois jeter dans un appel CompositionInitializer.SatisfyImports pour vous assurer que le FirstLevelView résout sa référence ViewModel.

Pour obtenir une instance de la EventsAggregator dans le SecondLevel ViewModel J'utilise:

<ImportingConstructor()> 
    Public Sub New(ByVal iEvAggregator As IEventAggregator) 
      EventAggregator = iEvAggregator 
      EventAggregator.GetEvent(Of DoStuffSecondLevel).Subscribe(AddressOf OnDoStuffSecondLevel, True) 

    End Sub 

Mon problème est que l'instance EventAggregator je reçois dans le deuxième modèle de vue niveau est différent de l'instance EventAggregator dans le premier niveau donc si je publie DoStuffSecondLevel au premier niveau, il ne sera pas pris au second niveau. Pourquoi ai-je deux instances différentes de l'EventAggregator?
Que puis-je faire pour partager la même instance de l'EventAggregator dans l'application?

Merci à l'avance

+0

Je voudrais ajouter à cela que j'ai rencontré le même problème. Je voudrais une solution où j'obtiens la MÊME INSTANCE en utilisant 'ComponentInitializer.SatisfyImports (this);' J'ai utilisé le 'ComponentInitializer.SatisfyImports (...)' pour que je puisse new() mes autres ViewModels (donc je ne Je n'ai pas besoin de réinitialiser manuellement leurs états), ce qui m'a conduit à utiliser les SatisfyImports pour obtenir mes services, principalement EventAggregator. – michael

+0

Veuillez vérifier quelques points: 1. Lorsque vous configurez votre conteneur MEF, définissez-vous la stratégie de création par défaut sur CreationPolicy.NonShared? 2. Possédez-vous un attribut PartCreationPolicy sur votre classe EventAggregator? 3. Est-il possible que vous créez un objet CompositionContainer distinct pour le secondLevelViewModel? –

Répondre

3

Le problème est que le MefBootstrapper crée un conteneur, mais ne l'enregistre pas comme conteneur DEFAULT. Lorsque SatisfyImports est appelé, MEF ne voit aucun conteneur, il en crée un nouveau. C'est pourquoi les instances sont différentes, car 2 conteneurs différents sont en cours de création. Pour résoudre ce problème, définissez simplement le conteneur Prism comme conteneur par défaut à utiliser par MEF.

Solution Silverlight (dans votre programme d'amorçage):

protected override void InitializeShell() 
{ 
    base.InitializeShell(); 

    //Make the container the default one. 
    CompositionHost.Initialize(this.Container); 

    //Etc. 
} 

WPF (Desktop) Solution:

Actuellement, je ne peux pas obtenir la solution de bureau pour travailler. Le problème est que les modèles ExportFactory<T> et ComponentInitializer de MEF sont uniquement disponibles pour les applications Silverlight (Why !?).Glen Block a créé une bibliothèque donnant accès à une version de bureau de la bibliothèque System.ComponentModel.Composition.Initialization.dll. J'ai essayé d'utiliser cela, mais il a échoué parce que dans le code, il est mis à échouer si un conteneur existe déjà ... encore une fois, pourquoi? Je n'ai pas encore essayé d'utiliser MEF2 (aperçu Codeplex) avec cette solution, mais j'imagine que cela fonctionnerait mieux (peut-être). La partie ennuyante est que si vous choisissez d'utiliser MEF2 (Codeplex), vous devez reconstruire les binaires Prism et remplacer toutes les références de la bibliothèque .NET 4 MEF par la bibliothèque Codeplex MEF2. Cela donne à Prism la possibilité de travailler avec la bibliothèque Codeplex MEF2 sans se plaindre. Je vais essayer de voir si cela rend cette solution viable avec WPF.

+0

La partie sliverlight a bien fonctionné. J'espère que vous pourrez aussi faire fonctionner la partie WPF. – michael

+0

@ m-y Avez-vous de la chance pour que cela fonctionne? –

+0

@BahriGungor: Je genre de fait, je suis arrivé Prism (Desktop) pour compiler en remplaçant les références System.ComponentModel avec les bibliothèques MEF2 (Codeplex), recompiler alors la solution. Je pense que cela inclus dans mon application WPF et référencé la bibliothèque MEF2 (Codeplex) au lieu de .NET 4 MEF. Cela m'a permis d'utiliser 'ExportFactor ', mais SatisfyImports était encore un peu bogué. –

Questions connexes