2014-02-21 13 views
6

Ich verwende den neuesten PRISM 4.2. Leider wird das Tutorial des Ereignisaggregators in der Dokumentation nicht über MEF, sondern über Unity gesteuert. Und ich kann es nicht unter MEF laufen lassen.Wie Ereignis Aggregator in MEF verwenden?

App.xaml.cs

public partial class App : Application 
    { 
     [Import] 
     public IEventAggregator eventAggregator; 

     protected override void OnStartup(StartupEventArgs e) 
     { 
      base.OnStartup(e); 

      Bootstrapper bootstrapper = new Bootstrapper(); 
      bootstrapper.Run(); 
     } 
    } 

Bootstrapper.cs

public class Bootstrapper : MefBootstrapper 
    { 
     protected override DependencyObject CreateShell() 
     { 
      return new MainWindow(); 
     } 

     protected override void InitializeShell() 
     { 
      base.InitializeShell(); 
      App.Current.MainWindow = (Window)Shell; 
      App.Current.MainWindow.Show(); 
     } 

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

      AggregateCatalog.Catalogs.Add(new AssemblyCatalog(this.GetType().Assembly)); 
     } 

     protected override IModuleCatalog CreateModuleCatalog() 
     { 
      ModuleCatalog moduleCatalog = new ModuleCatalog(); 

      return moduleCatalog; 
     } 

    } 

MainWindow.xaml.cs

public partial class MainWindow : Window, IView 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      DataContext = new MainViewModel(); 
     } 
    } 

MainViewModel.cs:

[ModuleExport(typeof(MainViewModel))] 
    public class MainViewModel : BindableBase, IServiceCallback 
    { 
     [Import] 
     public IEventAggregator eventAggregator; 

     [ImportingConstructor] 
     public MainViewModel() 
     {    
      eventAggregator.GetEvent<AppExitEvent>().Publish(""); 

     } 
    } 

Trotz der [import] des Ereignis-Aggregator ist immer null sowohl in App.xaml.cs und in MainViewModel. Warum das?
Die zweite Frage ist, muss ich meine Viewmodels als Modul exportieren (wie ich oben getan habe), um einen geraden Aggregator in ihnen zu verwenden?

UPDATE:

Proof, die neueste Version von PRISM nicht ComposeExportedValue mehr unterstützt.

enter image description here

'System.ComponentModel.Composition.Hosting.CompositionContainer' hat keine Definition für 'ComposeExportedValue' enthalten und keine Erweiterungsmethode ...

Antwort

7

Die Lösung hierfür wäre, was SchubertJ bei auf dieser Frage geantwortet CodePlex:

Als tiefen analyisis, der Import Attribut auf Eigenschaften würde nicht bis zum Konstruktor fin aufgelöst werden ishes. Aus diesem Grund müssten Sie die EventAggregator-Abhängigkeit über den Konstruktor als Parameter einfügen, wenn diese Abhängigkeit in der Konstruktorimplementierung verwendet würde.

Deshalb, wenn Sie die Eventaggregator Abhängigkeit von der Ansichtsmodell Konstruktor verwenden möchten, sollten Sie verwenden [ImportConstructor] Attribut statt und fragen Sie den Behälter für die Eventaggregator Instanz durch retreiving als Parameter:

public class MainViewModel 
{ 
    private readonly IEventAggregator eventAggregator; 

    [ImportingConstructor] 
    public MainViewModel(IEventAggregator eventAggregator) 
    { 
     this.eventAggregator = eventAggregator; 

     this.eventAggregator.GetEvent<MyEvent>().Publish(""); 
    } 
} 

Sie können mehr weiter gehende Informationen zu den beiden Import Alternativen im folgenden Beitrag finden:

Ich hoffe, das hat Ihnen geholfen, Grüße.

+0

Ja, das half. Danke vielmals. – Houman

+0

Froh, das zu hören. Hast du irgendwelche Vorschläge für meine Antwort, die dich nicht auf den neuesten Stand gebracht haben? Highlights, schlechte Erklärung vielleicht? Vielen Dank. – GOstrowsky

+0

Fertig. Akzeptierte Antwort auch. ;) – Houman

1

In Ihrer Bootstrap-Klasse haben Sie diese Methode:

protected override void ConfigureContainer() 
{ 
    base.ConfigureContainer(); 
    Container.ComposeExportedValue(new EventAggregator()); 
} 

Sie sollten sich das ansehen Artikel, wie es Ihre erste und zweite Frage in besseren Details beantwortet. http://www.gonetdotnet.info/posts/wpf-articles/wpf-module-communication

Update:

Wenn Sie eine Klasse erstellen, wie unten, damit er Ihren Export mit Ihrem Import übereinstimmen.

public class EventAggProvider 
    { 
    [Export(typeof(IEventAggregator))] 
    public IEventAggregator eventAggregator { get { return new EventAggregator(); } } 
    } 
+0

wo ist dein Artikel –

+0

Sind Sie sicher, dass Sie meinen nicht die 'ConfigureAggregateCatalog' statt' ConfigureContainer'? Ich dachte, dass ersteres die MEF Verschleißteile innerhalb der Anwendung handhabt. – Houman

+0

Ihr Artikel hat nichts mit MEF zu tun und eventagregator –

0

EventAggregator hängt nicht von MEF or Unity ist es Design-Muster von Martin Fowler geprägt und basiert auf Publisher-Teilnehmer Szenario

versuchen diese

Schritte zu folgen

// dies in Ihrer Infrastruktur Schicht sein sollte

public static class EventAggregatorHelper 
{ 
    private static IEventAggregator _Current = new EventAggregator(); 
    public static IEventAggregator Current 
    { 
    get 
    { 
     return _Current; 
    } 
    } 
} 



The HandleAppExitEvent is a class declared as shown below: 

public class AppExitEvent : CompositePresentationEvent<String> 
{ 
} 

and the subscriber would be something like this: 

in Ihrem MainWindow.xaml.cs

public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      DataContext = new MainViewModel(); 
//In this case the HandleAppExitEvent and the subscriber that deals with this event.     
EventAggregatorHelper.Current.GetEvent<AppExitEvent>(). Subscribe(HandleAppExitEvent); 

      } 
     //note that this method should be public 

public void HandleAppExitEvent(string mess) 
    { 
     if (!String.IsNullOrEmpty(mess)) 
     { 
      //Do whatever you need to do here. 
     } 
    } 

    } 
1

Es ist ein bisschen spät, aber es gibt auch eine Lösung für den Fall, in dem der EventAggregator in die Eigenschaft injiziert werden soll. Implementieren Sie 'IPartImportsSatisfiedNotification' und verwenden Sie den Ereignisaggregator in 'OnImportsSatisfied' Methode.

public class MainViewModel : BindableBase, IPartImportsSatisfiedNotification 
{ 
    [Import] 
    public IEventAggregator eventAggregator; 

    public void OnImportsSatisfied() 
    { 
     eventAggregator.GetEvent<AppExitEvent>().Publish(""); 
    } 
}