Houman Houman - 1 month ago 19
C# Question

How to utilise Event aggregator in MEF?

I am running the latest PRISM 4.2. Unfortunately the Event Aggregator tutorial in the documentation is driven via Unity instead of MEF. And I can't get it running under MEF.

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("");

}
}


Despite the
[import]
the event aggregator is always null both in App.xaml.cs and in MainViewModel. Why is that?

The second question is do I have to export my Viewmodels as a module (as I did above) to use an even aggregator inside them?

UPDATE:

Proof that latest version of PRISM doesn't support
ComposeExportedValue
anymore.

enter image description here


'System.ComponentModel.Composition.Hosting.CompositionContainer' does
not contain a definition for 'ComposeExportedValue' and no extension
method ...

Answer

The solution to this would be what SchubertJ replied on your same question at CodePlex:

As a deeper analyisis, the Import attribute on Properties would not be resolved until the constructor finishes. That is why you would need to inject the EventAggregator dependency through the constructor as a parameter if this dependency would be used on the constructor implementation.

Therefore, if you would like to use the EventAggregator dependency on the ViewModel constructor, you should use [ImportConstructor] attribute instead, and ask the container for the EventAggregator instance by retreiving it as a parameter:

public class MainViewModel
{
    private readonly IEventAggregator eventAggregator;

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

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

You may find more related information regarding both import alternatives in the following post:

I hope this helped you, Regards.