我正在运行最新的PRISM 4.2。不幸的是,文档中的Event Aggregator教程是通过Unity而不是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中始终为null。那是为什么?
第二个问题是我是否必须将我的Viewmodels导出为模块(如上所述)以在其中使用均匀聚合器?
更新
证明最新版本的PRISM不再支持ComposeExportedValue
。
&#39; System.ComponentModel.Composition.Hosting.CompositionContainer&#39;不 不包含&#39; ComposeExportedValue&#39;的定义没有延伸 方法......
答案 0 :(得分:7)
对此的解决方案将是 SchubertJ 在 CodePlex 的同一问题上回复:
作为更深入的分析,在构造函数完成之前,属性上的导入属性将无法解析。这就是为什么你需要通过构造函数注入 EventAggregator 依赖项作为参数,如果这个依赖项将用于构造函数实现。
因此,如果您想对 ViewModel 构造函数使用 EventAggregator 依赖关系,则应使用 [ImportConstructor] < / strong>属性,并通过将其作为参数进行检索,向容器询问 EventAggregator 实例:
public class MainViewModel
{
private readonly IEventAggregator eventAggregator;
[ImportingConstructor]
public MainViewModel(IEventAggregator eventAggregator)
{
this.eventAggregator = eventAggregator;
this.eventAggregator.GetEvent<MyEvent>().Publish("");
}
}
您可以在以下帖子中找到有关这两种导入替代方案的更多相关信息:
我希望这有助于你,问候。
答案 1 :(得分:1)
在你的bootstrapper类中有这个方法:
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(); } }
}
答案 2 :(得分:1)
这有点晚了,但是对于你希望EventAggregator注入属性的情况也有一个解决方案。实施“ IPartImportsSatisfiedNotification ”并在“ OnImportsSatisfied ”方法中使用eventaggregator。
public class MainViewModel : BindableBase, IPartImportsSatisfiedNotification
{
[Import]
public IEventAggregator eventAggregator;
public void OnImportsSatisfied()
{
eventAggregator.GetEvent<AppExitEvent>().Publish("");
}
}
答案 3 :(得分: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.
}
}
}