我正在尝试为我的应用程序设计一个事件聚合器。 (我是设计模式的新手,所以我可能还没有完全理解它。)
首先,我已经创建了一个有点聚合的解决方案,但需要改进和重构才能实现更高的效率并减少依赖性。
1)在Event Aggregator设计模式中,我的.NET数据源是否会被视为发布者? (我不确定出版商的角色是什么。)
2)我如何设计我的解决方案,不仅要处理特定数据源的订阅,还要处理特定数据事件而忽略其他数据?我希望看到一个解决方案,远离保持列表并不知疲倦地循环它们......但不确定我是否可以一起避免这一点。
答案 0 :(得分:1)
我认为你必须在这里实现一个好的发布者/订阅者。我的建议是这样的:
您的发布商:EventAggregator
应该有以下方法:
public void Register(IEventObserver observer, EventFilter filter)
public void Unregister(IEventObserver observer)
您的IEventObserver
应该是
public interface IEventObserver
{
void Notify(object eventSource, DetailedEventArgs e);
}
您的订阅者应该实现此界面。
您的EventFilter
类应具有您打算使用的所有过滤属性。
这个类可以有这样的方法:
public bool IsSatisfiedBy(DetailedEventArgs e)
并创建一个名为DetailedEventArgs
的类并从EventArgs
继承它,将有关事件的所有详细信息放在其中。
在Register
方法中,您应该存储过滤器和观察者。现在当你的EventAggregator
捕获一个事件时,它应首先从接收到的事件中创建DetailedEventArgs
对象,然后循环观察者及其过滤器以查看对象是否满足过滤器,如果是,使用原始发件人和DetailedEventArgs
对象调用观察者的Notify方法。
我强烈建议您检查发布方而非订阅方的过滤器。因为检查用户端会使大量代码重复和不一致。
编辑:示例EventFilter
和DetailedEventArgs
类:
public class EventFilter
{
private List<Type> SourceTypes;
private List<EventType> EventTypes;
public EventFilter() : this(new Type[] { }, new EventType[] { }) { }
public EventFilter(IEnumerable<Type> sourceTypes, IEnumerable<EventType> eventTypes)
{
SourceTypes = new List<Type>(sourceTypes);
EventTypes = new List<EventType>(eventTypes);
}
public void AddSourceType(Type type)
{
AddItemToList(SourceTypes, type);
}
public void AddEventType(EventType type)
{
AddItemToList(EventTypes, type);
}
private void AddItemToList<T>(List<T> list, T item)
{
lock (list)
{
if (!list.Contains(item))
list.Add(item);
}
}
public bool IsSatisfiedBy(DetailedEventArgs args)
{
return SourceTypes.Contains(args.Source.GetType()) && EventTypes.Contains(args.EventType);
}
}
public class DetailedEventArgs : EventArgs
{
public EventArgs SourceArgs { get; private set; }
public object Source { get; private set; }
public EventType EventType { get; private set; }
public DetailedEventArgs(object source, EventArgs sourceArgs, EventType eventType)
{
Source = source;
SourceArgs = sourceArgs;
EventType = eventType;
}
}
public enum EventType
{
EventType1,
EventType2,
EventType3
}
希望我帮忙:)
答案 1 :(得分:0)
查看MVVM Light Messenger课程。我的实现基于此。但是,它使用了列表和循环,但我没有看到解决方法。
我看到一些关于内存泄漏的抱怨,但它没有影响我,可能会被修复。