我正在使用Prism实现事件聚合.我有几个模块,我希望他们每个人订阅事件,告诉他们什么时候被请求.我开始用shell中的订阅和发布者做一个简单的例子.没有问题.现在; 当我将订户移到我的模块时,他们不会被触发.更奇怪的是它实际上已经工作了几次 - 所有这些我都在断点中待定.所以在我看来是一些竞争条件,但我不明白为什么.
假设:我不需要在任何地方设置IEventAggregator - 例如在IoC容器中注册?这是内置于Prism中的,因此我只有一个事件聚合器实例,对吗?
所以,问题基本上是我应该如何/何时/何时设置我的订阅者.东西等有特定的订单吗?在我的简化示例中,我有一个模块MyModule.Bootstrapper会将MyModule添加到目录中 - 使其初始化:
catalog.AddModule(typeof(MyModule));
Run Code Online (Sandbox Code Playgroud)
MyModule将存储聚合器并使用它来订阅MyModuleRequestedEvent.它还使用菜单注册表在应用程序菜单中注册.这个想法是最终点击菜单应该触发事件 - 通知MyModule它已被请求.然后我希望MyModule有责任弄清楚该做些什么.
public MyModule(IEventAggregator aggregator, IApplicationMenuRegistry menu)
{
_applicationMenu = menu;
_aggregator = aggregator;
}
public void Initialize()
{
var evnt = _aggregator.GetEvent<MyModuleRequestedEvent>();
evnt.Subscribe(MyModuleRequested);
_applicationMenu.RegisterMenuItem("MyModule", evnt);
}
public void MyModuleRequested(bool b)
{
MessageBox.Show("MyModule requested");
}
Run Code Online (Sandbox Code Playgroud)
现在,我的shell中有一个按钮,可以发布此事件.shell在解析时获得相同的(?)事件聚合器.
public Shell(IEventAggregator aggregator)
{
InitializeComponent();
var evnt = aggregator.GetEvent<MyModuleRequestedEvent>();
EventTriggerButton.Click += (s, e) => evnt.Publish(true);
}
Run Code Online (Sandbox Code Playgroud)
笔记:
我有许多骨干模型,按集合进行组织并连接到相应的视图和/或视图集合.其中一些不属于同一集合的模型需要触发另一个模型(可能不止一个)感兴趣的事件.
我认为,推荐的处理方法是这里和其他地方所描述的"全球事件调度员/聚合器" .
但是,我也碰巧使用require.js,这似乎违背了将调度程序/聚合器附加到应用程序的命名空间对象的想法 - 或者我错在这里?
所以我的问题是:使用require.js我怎么能有一些不同的骨干模型触发一个将由另一个模型处理的事件?
我试图以一种简单的方式实现事件聚合器模式,逐步学习它.但我没有找到任何书或好的视频教程谈论它的实现.
我刚刚发现了一些很好的文章,例如http://weblogs.asp.net/rashid/archive/2009/03/05/use-event-aggregator-to-make-your-application-more-extensible.aspx和http ://martinfowler.com/eaaDev/EventAggregator.html第一篇文章太大,让我不了解模式,第二篇文章没有完成:).
顺便说一句,我创建了我的课程:
public class Member
{
public int ID { get; set; }
public string UserName { get; set; }
}
public class MemberService
{
public void CommentSubmited()
{
// increase member score and do some other logic.
}
}
public class Comment
{
public int ID { get; set; }
public string CommentBody { get; set; }
public Member ByMember { get; set; }
}
public class CommentService
{
public void SubmitNewComment(Member member, …Run Code Online (Sandbox Code Playgroud) 我通过Prism指导工作,并认为我掌握了他们的大多数通信工具.
命令非常简单,因此很明显DelegateCommand仅用于将View与其模型连接起来.
当涉及交叉模块通信时,特别是何时使用EventAggregation而不是复合命令时,它有点不太清楚.
实际效果是相同的,例如
两者都按照"发射并忘记"的方式工作,即他们在触发事件/执行命令后不关心其订户的任何响应.
我很难看到使用中的实际差异,虽然我知道两者(引擎盖下)的实现是非常不同的.
那么我们应该想一想它的实际含义 - 事件?是什么事情发生(事件发生)?用户没有像"完成网页请求"那样直接请求的内容?
和命令?这是否意味着用户点击了某些东西,从而向我们的应用程序发出命令,直接请求服务?
是吗?或者是否有其他方法可以确定何时使用其中一种通信工具而不是另一种.该指南虽然是我读过的最好的文件之一,却没有给出具体的解释.
因此,我希望参与/使用棱镜的人可以帮助揭示这一点.
我有一个课程,通过PRISMs事件聚合器订阅一个事件.
由于这里提到的模拟事件聚合器有点困难,我只是实例化一个真实聚合器并将其传递给被测系统.
在我的测试中,我然后通过该聚合器发布事件,然后检查我的测试系统如何对它做出反应.由于事件将在生产期间由FileSystemWatcher引发,我想通过订阅UIThread来使用自动分派,因此我可以在引发事件后更新我的UI.
问题是,在测试期间,除非我没有订阅UIThread,否则事件永远不会在被测系统中被注意到.
我正在使用MSpec进行测试,我通过TDD.Net从VS2008内部运行.添加[RequiresSta]到我的测试类没有帮助
有没有人有一个解决方案,这使我免于在测试期间更改ThreadOption(例如通过属性 - 这是一个丑陋的黑客)???
我有一个做CRUD的应用程序Collection中Models.DisplayView每个模型都有一个始终可见的模型.还有一个EditView仅在DisplayView单击关联时才可见.
在DisplayView和EditView出现的不同意见父里面.现在我正在使用"事件聚合器"模式告诉我的应用程序渲染EditView时DisplayView单击a.此处描述的模式:http://lostechies.com/derickbailey/2011/07/19/references-routing-and-the-event-aggregator-coordinating-views-in-backbone-js/
当我DisplayView点击其中一个时,它会触发一个EditViews侦听父级的事件.当它收到此事件时,它会EditView根据触发事件的模型呈现适当的事件.
这适用于我的大多数应用程序,但是当我想EditView根据DisplayView我的应用程序中相关的绝对位置获得更改位置时,这特别麻烦.它不是DisplayView直接控制位置EditView,而是触发"请将自己重新定位到这些坐标"事件.这种直接通信并不像应该向整个应用程序广播的东西.我开始怀疑,对于我的情况,我应该只是引用适当的EditView作为每个属性DisplayView而不是将它们分离.
正如我所说,问题在于它们是在不同的父视图中呈现的.在DisplayViews得到呈现的HeaderView,而在EditViews得到呈现的ContentView.
其他人如何处理这样的情况?将EditView在某些方面属于DisplayView,但是,这并不符合我的应用程序的DOM的结构方式.假设我创建的每个之间的直接联系EditView和DisplayView,我将如何处理的显示/隐藏EditView?是否DisplayView还需要对ContentView容器的引用,它将使用适当EditView的参数显式呈现?
我学习卡利微并尝试使用的EventAggregator从官方网站.
但是,我有一个例外
"没有为此对象定义无参数构造函数."
消息本身很清楚,但示例中也没有包含无参数构造函数.如果我添加一个,带有参数的构造函数不会被命中,IEventAggregator仍然没有正确注入.
添加无参数构造函数后,这是我的发布者VM(没有它,将抛出异常):
public MainViewModel() { }
public MainViewModel(IEventAggregator ea) : this()
{
eventAggregator = ea;
}
Run Code Online (Sandbox Code Playgroud)
这是我正在使用的引导程序:
public class AppBootstrapper : Bootstrapper<MainViewModel>
{
private readonly SimpleContainer container = new SimpleContainer();
protected override void Configure()
{
container.Singleton<IEventAggregator, EventAggregator>();
}
}
Run Code Online (Sandbox Code Playgroud)
这是CM的例子:
// Creating the EventAggregator as a singleton.
public class Bootstrapper : BootstrapperBase {
private readonly SimpleContainer _container =
new SimpleContainer();
// ... Other Bootstrapper Config
protected override void Configure(){
_container.Singleton<IEventAggregator, EventAggregator>(); …Run Code Online (Sandbox Code Playgroud) 在Caliburn.Micro文档中,作者提到了这种可能性:
IHandle继承自标记接口IHandle.这允许使用强制转换来确定对象实例是否订阅任何事件.如果您与IoC容器集成,则可以实现简单的自动订阅.大多数IoC容器(包括SimpleContainer)提供了一个钩子,用于在创建新实例时调用它.只需连接容器的回调,检查正在创建的实例以查看它是否实现IHandle,如果是,请在事件聚合器上调用Subscribe.
如何通过Autofac实现这一目标?
我试图利用装饰器的功能,但当然这对于这种情况来说是不合适的.更重要的是,默认情况下,IHandle <>的实现者没有在容器中注册为IHandle的实例.
PS提供这种不正确的实现以防万一它可能有用,但我怀疑.
builder.RegisterInstance<IEventAggregator>(new EventAggregator());
builder.RegisterDecorator<IHandle>((container, handler) =>
{
var eventAggregator = container.Resolve<IEventAggregator>();
eventAggregator.Subscribe(handler);
return handler;
}, "unsubscribed", "subscribed");
Run Code Online (Sandbox Code Playgroud) backbone.wreqr对js 对象有哪些主要好处,两种情况都可以访问牵线木偶的事件聚合器.
不会从对象分配/调用方法的工作方式与Commands/RequestResponse相同.对我来说,除了给语义/可读性+1之外,我认为没有必要实现这一点.
https://github.com/marionettejs/backbone.wreqr
有人可以赐教,这是我的第一个骨干(和模块化)应用程序.
eventaggregator ×10
prism ×4
backbone.js ×3
c# ×3
javascript ×2
wpf ×2
.net ×1
autofac ×1
events ×1
marionette ×1
messaging ×1
modularity ×1
module ×1
requirejs ×1
tdd ×1
ui-thread ×1