好的,
这个问题是针对那些对 PRISM 有深入了解或我还缺乏一些魔法技能的人。背景很简单:Prism 允许声明用户可以订阅或发布的事件。在代码中,它看起来像这样:
_eventAggregator.GetEvent<LayoutChangedEvent>().Subscribe(UpdateUi, true);
_eventAggregator.GetEvent<LayoutChangedEvent>().Publish("Some argument");
现在这很好,特别是因为这些事件是强类型的,并且声明是小菜一碟:
public class LayoutChangedEvent : CompositePresentationEvent<string>
{
}
但现在困难的部分来了:我想以某种方式跟踪事件。我的想法是使用 lambda 表达式调用简单的日志消息进行订阅。在 WPF 中工作得很好,但在 Silverlight 中出现了一些方法访问错误(我花了一些时间才找出原因)。如果您想亲自查看,请在 Silverlight 中尝试一下:
eA.GetEvent<VideoStartedEvent>().Subscribe(obj => TraceEvent(obj, "vSe", log));
如果这是可能的,我会很高兴,因为我可以使用单行订阅轻松跟踪所有事件。但事实并非如此...另一种方法是为每个事件编写不同的函数,并将该函数分配给事件。为什么功能不同?好吧,我需要知道发布了哪个事件。如果我对两个不同的事件使用相同的函数,我只会得到有效负载作为参数。我现在可以找出哪个事件导致了跟踪消息。
我尝试过:
- 使用反射来获取引发事件(不起作用)
- 在事件中使用构造函数使每个事件能够跟踪自身(不允许)
还有其他想法吗? 克里斯
PS:写这篇文章很可能比为 20 个事件编写 20 个函数花费的时间更长,但我拒绝放弃:-) 我只是想到使用 postsharp,这很可能会起作用(尽管我不是)当然,也许我最终只有有关基类的信息)..棘手且不重要的主题...
最佳答案
最简单的事情可能是子类化 CompositePresentationEvent 并覆盖 Publish 事件的行为。这是 CompositePresentationEvent 的来源: http://compositewpf.codeplex.com/SourceControl/changeset/view/26112#496659
以下是当前的发布行为:
public virtual void Publish(TPayload payload)
{
base.InternalPublish(payload);
}
所以你可以添加一点:
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);
}
这里我使用的是 Prism 中内置的记录器工具,但您可以随意替换您自己的记录器工具(或者更好,只需实现 ILoggerFacade!)。
令我惊讶的是,这个系统中竟然有任何默认消息被发布或可以插入跟踪...尽管 EventAggregator 被人们滥用,你会认为这将是一个很大的请求!
关于c# - 跟踪 PRISM/CAL 事件(最佳实践?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1528876/