2011-05-19 7 views
5

I tienen la siguiente configuración:Prism: EventAggregator y MEF - 2 instancias diferentes de EventAggregator

  • una división aplicación Silverlight través xaps/módulos
  • utilizo MEF como marco DI para conectar varias partes de mi aplicación.

  • tengo 2 regiones:

  • One (el de la izquierda) se rellena con una vista de lista (por ejemplo, clientes)

  • One (el derecho) se rellena con una vista que contenga un tabcontrol con una región que rellené (según a la que se selecciona cliente) con otra vista que contiene un control de pestaña con una región.

    El resultado lado derecho: enter image description here

para poblar el primer nivel tabcontrol estoy escuchando el "evento cambiado al cliente" - (esto funciona muy bien) y cuando llego a recibir el evento que pueblan el en primer área de la ficha de nivel con Vistas:

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 

Nota: al crear el FirstLevelView tengo que tirar en una llamada CompositionInitializer.SatisfyImports para asegurarse de que el FirstLevelView resuelve su referencia de ViewModel.

para obtener una instancia de la EventsAggregator en el SecondLevel modelo de vista que utilizo:

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

    End Sub 

Mi problema es que la instancia EventAggregator me sale en el segundo modelo de vista nivel es diferente de la instancia EventAggregator en el primer nivel entonces, si publico DoStuffSecondLevel en el primer nivel, no quedará atrapado en el segundo nivel.

¿Por qué obtengo 2 instancias diferentes del EventAggregator?
¿Qué puedo hacer para compartir la misma instancia del EventAggregator en la aplicación?

Gracias de antemano

+0

Me gustaría añadir que me encontré con el mismo problema. Me gustaría una solución en la que obtenga la MISMA INSTANCIA utilizando el 'ComponentInitializer.SatisfyImports (this);' Utilicé el 'ComponentInitializer.SatisfyImports (...)' para que pueda new() mis otros ViewModels (así que No tengo que restablecer sus estados manualmente), lo que me llevó a utilizar SatisfyImports para poder obtener mis servicios, principalmente el EventAggregator. – michael

+0

Compruebe algunas cosas: 1. Cuando configura su contenedor MEF, ¿está configurando la política de creación predeterminada en CreationPolicy.NonShared? 2. ¿Tiene un atributo PartCreationPolicy en su clase EventAggregator? 3. ¿Es posible que esté creando un objeto CompositionContainer separado para SecondLevelViewModel? –

Respuesta

3

El problema es que el MefBootstrapper crea un contenedor, pero no se registra como el contenedor predeterminado. Cuando se llama a SatisfyImports, MEF no ve ningún contenedor, por lo que crea uno nuevo. Es por eso que las instancias son diferentes, porque se están creando 2 contenedores diferentes. Para resolver esto, simplemente configure el Prism Container como el contenedor predeterminado para que MEF lo use.

Solución Silverlight (en su programa previo):

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

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

    //Etc. 
} 

WPF (Escritorio) Solución:

En la actualidad, no se puede obtener la solución de escritorio para trabajar. El problema es que ExportFactory<T> y ComponentInitializer de MEF solo están disponibles para las aplicaciones de Silverlight (¿Por qué?).Glen Block creó una biblioteca que da acceso a una versión de escritorio de la biblioteca System.ComponentModel.Composition.Initialization.dll. Intenté usar eso, pero falló porque en el código está configurado para fallar si ya existe un contenedor ... otra vez, ¿por qué? No intenté usar MEF2 (vista previa de Codeplex) con esta solución todavía, pero me imagino que funcionaría mejor (tal vez). La parte molesta es que si eliges usar MEF2 (Codeplex) debes reconstruir los binarios de Prism y reemplazar todas las referencias de la biblioteca .NET 4 MEF con la biblioteca Codeplex MEF2. Eso le da a Prism la capacidad de trabajar con la biblioteca Codeplex MEF2 sin quejarse. Trataré de ver si hacer eso hace que esta solución sea viable con WPF.

+0

La parte de la luz de cola funcionó de maravilla. Espero que puedas hacer que la parte de WPF también funcione. – michael

+0

@ m-y ¿Alguna suerte de conseguir que esto funcione? –

+0

@BahriGungor: De alguna manera lo hice, obtuve Prism (Desktop) para compilar reemplazando las referencias System.ComponentModel con las librerías MEF2 (Codeplex), luego volviendo a compilar la solución. Creo que incluí esto en mi aplicación WPF y mencioné la biblioteca MEF2 (Codeplex) en lugar de .NET 4 MEF. Me permitió usar 'ExportFactor ', pero SatisfyImports aún tenía problemas. –

Cuestiones relacionadas