0

我正在尝试为我的应用程序设计一个事件聚合器。(我是设计模式的新手,所以我可能还没有完全理解它)。

首先,我已经创建了一个解决方案,它在某种程度上是一个聚合器,但需要改进和重构以实现更高的效率并减少依赖关系。

1) 在事件聚合器设计模式中,我的 .NET 数据源是否会被视为发布者?(我不确定出版商的角色是)。

2) 我将如何设计我的解决方案来处理不仅对特定数据源的订阅,而且还能处理特定数据事件而忽略其他事件?我希望看到一种解决方案,它可以摆脱保留列表并不知疲倦地循环遍历它们……但不确定我是否可以一起避免这种情况。

4

2 回答 2

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从接收到的事件中创建对象,然后循环观察者及其过滤器以查看过滤器是否被对象满足,如果满足,则使用原始发送者调用观察者的 Notify 方法和DetailedEventArgs对象。

我强烈建议您检查发布者端而不是订阅者端的过滤器。因为签入订户端会使大量代码重复和不一致。

编辑:一个例子EventFilterDetailedEventArgs类:

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
}

希望我有所帮助:)

于 2011-12-06T22:18:13.133 回答
0

查看MVVM Light Messenger类。我的实现基于此。但是,它使用列表和循环,但我没有看到解决方法。

我看到了一些关于内存泄漏的投诉,但它并没有影响到我,并且可能会得到修复。

于 2011-12-06T19:28:13.337 回答