好,
这个问题适用于对PRISM有深入了解的人或者我缺乏的一些魔法技能.背景很简单:Prism允许声明用户可以订阅或发布的事件.在代码中,这看起来像这样:
_eventAggregator.GetEvent<LayoutChangedEvent>().Subscribe(UpdateUi, true);
_eventAggregator.GetEvent<LayoutChangedEvent>().Publish("Some argument");
Run Code Online (Sandbox Code Playgroud)
现在这很好,特别是因为这些事件是强类型的,声明是小菜一碟:
public class LayoutChangedEvent : CompositePresentationEvent<string>
{
}
Run Code Online (Sandbox Code Playgroud)
但现在是困难的部分:我想以某种方式追踪事件.我有想法使用lambda表达式订阅调用简单的日志消息.在WPF中工作得很好,但在Silverlight中有一些方法访问错误(花了我一些时间来弄清楚原因)..如果你想亲眼看看,请在Silverlight中尝试:
eA.GetEvent<VideoStartedEvent>().Subscribe(obj => TraceEvent(obj, "vSe", log));
Run Code Online (Sandbox Code Playgroud)
如果这是可能的,我会很高兴,因为我可以使用一行来轻松跟踪所有事件进行订阅.但它没有...替代方法是为每个事件编写不同的函数,并将此函数分配给事件.为什么功能不同?好吧,我需要知道哪个事件发布了.如果我对两个不同的事件使用相同的函数,我只将有效负载作为参数.我现在可以找出导致跟踪消息的事件.
我试过了:
还有其他想法吗?克里斯
PS:写这篇文章花了我很可能比为我的20个事件编写20个函数更长,但我拒绝放弃:-)我只是想使用postharp,这很可能会工作(虽然我不确定,也许我最终只有关于基类的信息)..棘手和如此不重要的话题......
可能最简单的方法是继承CompositePresentationEvent并覆盖Publish事件的行为.这是CompositePresentationEvent的源代码:http: //compositewpf.codeplex.com/SourceControl/changeset/view/26112#496659
这是当前的Publish行为:
public virtual void Publish(TPayload payload)
{
base.InternalPublish(payload);
}
Run Code Online (Sandbox Code Playgroud)
所以你可以添加一点:
public virtual override void Publish(TPayload payload)
{
ILoggerFacade logger = ServiceLocator.Current.GetInstance<ILoggerFacade>();
logger.Log("Publishing " + payload.ToString(), Category.Debug, Priority.Low);
base.InternalPublish(payload);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我使用Prism内置的记录器工具,但可以随意替换自己(或更好,只需实现ILoggerFacade!).
我很惊讶在这个系统中发布了任何默认消息或插入跟踪的地方......尽管EventAggregator被人滥用,你会认为这是一个很大的要求!