2014-02-21 17 views
6

我正在運行最新的PRISM 4.2。不幸的是,文檔中的Event Aggregator教程是通過Unity而不是MEF驅動的。我無法在MEF下運行。如何在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(""); 

     } 
    } 

儘管[import]事件聚合總是空無論是在App.xaml.cs和MainViewModel。這是爲什麼?
第二個問題是我必須將我的Viewmodels作爲模塊導出(就像我上面所做的那樣)以在其中使用一個聚合器?

UPDATE:

證明的PRISM最新版本不支持ComposeExportedValue了。

enter image description here

'System.ComponentModel.Composition.Hosting.CompositionContainer' 並不 不包含 'ComposeExportedValue' 和沒有擴展 方法的定義...

回答

7

對此的解決辦法是什麼SchubertJ您同樣的問題回答在CodePlex上

至於更深analyisis的導入屬性上的屬性直到構造函數fin纔會被解析ishes。這就是爲什麼如果在構造函數實現中使用此依賴項,您需要通過構造函數注入依賴關係作爲參數。

因此,如果您想使用的視圖模型構造的EventAggregator依賴,你應該使用[ImportConstructor]屬性代替,並通過retreiving它索要EventAggregator實例的容器作爲一個參數:

public class MainViewModel 
{ 
    private readonly IEventAggregator eventAggregator; 

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

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

您可能會發現更多的相關信息,關於在下面的帖子都進口替代:

我希望這有助於你的問候。

+0

是的,這有幫助。非常感謝。 – Houman

+0

很高興聽到這個消息。但是,你有沒有對我的答案有任何建議,但沒有讓你高興呢?亮點,可能的問題解釋不好?謝謝。 – GOstrowsky

+0

完成。接受的答案也是如此。 ;) – Houman

1

在你的引導程序類有這種方法:

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

你應該看看這個文章,因爲它是更好的細節回答你的第一個和第二個問題。 http://www.gonetdotnet.info/posts/wpf-articles/wpf-module-communication

更新:

如果你創建一個類,如下它將你的出口與進口的匹配。

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

您的文章在哪兒 –

+0

您確定您不是指'ConfigureAggregateCatalog'而不是'ConfigureContainer'嗎?我認爲前者在應用程序中處理MEF易損件。 – Houman

+0

你的文章與MEF和eventagregator –

0

EventAggregator不依賴於MEF or Unity這是由Martin Fowler創造的設計模式,它是基於發行商的用戶場景

儘量按照這個步驟

//這應該是你的基礎設施層

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: 

在您的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

這有點晚,但也有一個解決方案,您希望EventAggregator被注入到屬性中。執行'IPartImportsSatisfiedNotification',並在'OnImportsSatisfied'方法中使用eventaggregator。

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

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