事件聚合器:需要帮助修改解决方案

发布于 2024-12-19 18:13:59 字数 293 浏览 1 评论 0原文

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

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

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

2)我将如何设计我的解决方案来不仅处理特定数据源的订阅,还处理特定数据事件的订阅,同时忽略其他数据事件?我希望看到一个解决方案,不再保留列表并不知疲倦地循环它们......但不确定我是否可以一起避免这一切。

I'm attempting to design an event aggregator for my application. (I am new to the design pattern, so I may not fully understand it yet).

Firstly, I have created a solution already that is somewhat an aggregator but needs improvement and refactoring to achieve better efficiency and lessen dependencies.

1) In the Event Aggregator design pattern, would my .NET data sources be considered the publishers? (I'm uncertain about the publishers' role is).

2) How would I design my solution to handle subscriptions not only to specific data sources, but also specific data events while ignoring others? I would like to see a solution that moves away from keeping lists and looping through them tirelessly.. but not sure if I can avoid this all together.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏有森光若流苏 2024-12-26 18:13:59

我认为你必须在这里实现一个好的发布者/订阅者。我的建议是这样的:

您的发布者: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 方法。

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

编辑:示例 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
}

希望我有所帮助:)

I think you have to implement a good publisher/subscriber here. My suggestion is something like this:

your publisher: EventAggregator should have methods like:

public void Register(IEventObserver observer, EventFilter filter)
public void Unregister(IEventObserver observer)

your IEventObserver should look like

public interface IEventObserver
{
    void Notify(object eventSource, DetailedEventArgs e);
}

your subscribers should implement this interface.

your EventFilter class should have all the filtering properties that you intend to use.
this class can have a method like this:

public bool IsSatisfiedBy(DetailedEventArgs e)

and create a class Named DetailedEventArgs and inherit it from EventArgs, put all the details you want about an event on that.

in the Register method, you should store both filters and observers. now when your EventAggregator catches an event, it should first create the DetailedEventArgs object from the received event, and then loop the observers and their filters to see if the filter is satisfied by the object and if so, call the Notify method of observer with the original sender and DetailedEventArgs object.

I seriously recommend you to check the filter on publisher side and not the subscriber side. because checking in subscriber side will make lots of code duplicate and inconsistency.

EDIT: An example EventFilter and DetailedEventArgs classes:

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
}

hope I helped :)

淡忘如思 2024-12-26 18:13:59

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

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

Check out the MVVM Light Messenger class. I based my implementation on that. However, it uses lists and loops, but I don't see a way around that.

I have seen some complaints about a memory leak, but it has not impacted me, and may be fixed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文