.NET 的简单事件总线

发布于 2024-07-09 23:01:53 字数 1560 浏览 10 评论 0原文

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

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

发布评论

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

评论(8

梦亿 2024-07-16 23:01:53

Tiny Messenger 是一个不错的选择,我已经在现场项目中使用它 2.5 年了。 来自 Wiki 的一些代码示例(链接如下):

发布

messageHub.Publish(new MyMessage());

订阅

messageHub.Subscribe<MyMessage>((m) => { MessageBox.Show("Message Received!"); });
messageHub.Subscribe<MyMessageAgain>((m) => { MessageBox.Show("Message Received!"); }, (m) => m.Content == "Testing");

代码位于 GitHub 上:https://github.com/grumpydev/TinyMessenger

Wiki 位于: https://github.com/grumpydev/TinyMessenger/wiki

它还有一个 Nuget 包

Install-Package TinyMessenger

Tiny Messenger is a good choice, I've been using it in a live project for 2.5 years now. Some code examples from the Wiki (link below):

Publishing

messageHub.Publish(new MyMessage());

Subscribing

messageHub.Subscribe<MyMessage>((m) => { MessageBox.Show("Message Received!"); });
messageHub.Subscribe<MyMessageAgain>((m) => { MessageBox.Show("Message Received!"); }, (m) => m.Content == "Testing");

The code's on GitHub: https://github.com/grumpydev/TinyMessenger

The Wiki is here: https://github.com/grumpydev/TinyMessenger/wiki

It has a Nuget package also

Install-Package TinyMessenger
初雪 2024-07-16 23:01:53

另一种,受 Android 的 EventBus 启发,但简单得多:

public class EventBus
{
    public static EventBus Instance { get { return instance ?? (instance = new EventBus()); } }

    public void Register(object listener)
    {
        if (!listeners.Any(l => l.Listener == listener))
            listeners.Add(new EventListenerWrapper(listener));
    }

    public void Unregister(object listener)
    {
        listeners.RemoveAll(l => l.Listener == listener);
    }

    public void PostEvent(object e)
    {
        listeners.Where(l => l.EventType == e.GetType()).ToList().ForEach(l => l.PostEvent(e));
    }

    private static EventBus instance;

    private EventBus() { }

    private List<EventListenerWrapper> listeners = new List<EventListenerWrapper>();

    private class EventListenerWrapper
    {
        public object Listener { get; private set; }
        public Type EventType { get; private set; }

        private MethodBase method;

        public EventListenerWrapper(object listener)
        {
            Listener = listener;

            Type type = listener.GetType();

            method = type.GetMethod("OnEvent");
            if (method == null)
                throw new ArgumentException("Class " + type.Name + " does not containt method OnEvent");

            ParameterInfo[] parameters = method.GetParameters();
            if (parameters.Length != 1)
                throw new ArgumentException("Method OnEvent of class " + type.Name + " have invalid number of parameters (should be one)");

            EventType = parameters[0].ParameterType;
        }

        public void PostEvent(object e)
        {
            method.Invoke(Listener, new[] { e });
        }
    }      
}

用例:

public class OnProgressChangedEvent
{

    public int Progress { get; private set; }

    public OnProgressChangedEvent(int progress)
    {
        Progress = progress;
    }
}

public class SomeForm : Form
{
    // ...

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        EventBus.Instance.Register(this);
    }

    public void OnEvent(OnProgressChangedEvent e)
    {
        progressBar.Value = e.Progress;
    }

    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        EventBus.Instance.Unregister(this);
    }
}

public class SomeWorkerSomewhere
{
    void OnDoWork()
    {
        // ...

        EventBus.Instance.PostEvent(new OnProgressChangedEvent(progress));

        // ...
    }
}

Another one, inspired by EventBus for android, but far simpler:

public class EventBus
{
    public static EventBus Instance { get { return instance ?? (instance = new EventBus()); } }

    public void Register(object listener)
    {
        if (!listeners.Any(l => l.Listener == listener))
            listeners.Add(new EventListenerWrapper(listener));
    }

    public void Unregister(object listener)
    {
        listeners.RemoveAll(l => l.Listener == listener);
    }

    public void PostEvent(object e)
    {
        listeners.Where(l => l.EventType == e.GetType()).ToList().ForEach(l => l.PostEvent(e));
    }

    private static EventBus instance;

    private EventBus() { }

    private List<EventListenerWrapper> listeners = new List<EventListenerWrapper>();

    private class EventListenerWrapper
    {
        public object Listener { get; private set; }
        public Type EventType { get; private set; }

        private MethodBase method;

        public EventListenerWrapper(object listener)
        {
            Listener = listener;

            Type type = listener.GetType();

            method = type.GetMethod("OnEvent");
            if (method == null)
                throw new ArgumentException("Class " + type.Name + " does not containt method OnEvent");

            ParameterInfo[] parameters = method.GetParameters();
            if (parameters.Length != 1)
                throw new ArgumentException("Method OnEvent of class " + type.Name + " have invalid number of parameters (should be one)");

            EventType = parameters[0].ParameterType;
        }

        public void PostEvent(object e)
        {
            method.Invoke(Listener, new[] { e });
        }
    }      
}

Use case:

public class OnProgressChangedEvent
{

    public int Progress { get; private set; }

    public OnProgressChangedEvent(int progress)
    {
        Progress = progress;
    }
}

public class SomeForm : Form
{
    // ...

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        EventBus.Instance.Register(this);
    }

    public void OnEvent(OnProgressChangedEvent e)
    {
        progressBar.Value = e.Progress;
    }

    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        EventBus.Instance.Unregister(this);
    }
}

public class SomeWorkerSomewhere
{
    void OnDoWork()
    {
        // ...

        EventBus.Instance.PostEvent(new OnProgressChangedEvent(progress));

        // ...
    }
}
情归归情 2024-07-16 23:01:53

复合应用程序块包含一个事件代理,可能用于你。

The Composite Application Block includes an event broker that might be of use to you.

捂风挽笑 2024-07-16 23:01:53

您还可以查看 Unity 扩展:
http://msdn.microsoft.com/en-us/library/cc440958。 aspx

[Publishes("TimerTick")]
public event EventHandler Expired;
private void OnTick(Object sender, EventArgs e)
{
  timer.Stop();
  OnExpired(this);
}

[SubscribesTo("TimerTick")]
public void OnTimerExpired(Object sender, EventArgs e)
{
  EventHandler handlers = ChangeLight;
  if(handlers != null)
  {
    handlers(this, EventArgs.Empty);
  }
  currentLight = ( currentLight + 1 ) % 3;
  timer.Duration = lightTimes[currentLight];
  timer.Start();
}

有更好的吗?

You might also check out Unity extensions:
http://msdn.microsoft.com/en-us/library/cc440958.aspx

[Publishes("TimerTick")]
public event EventHandler Expired;
private void OnTick(Object sender, EventArgs e)
{
  timer.Stop();
  OnExpired(this);
}

[SubscribesTo("TimerTick")]
public void OnTimerExpired(Object sender, EventArgs e)
{
  EventHandler handlers = ChangeLight;
  if(handlers != null)
  {
    handlers(this, EventArgs.Empty);
  }
  currentLight = ( currentLight + 1 ) % 3;
  timer.Duration = lightTimes[currentLight];
  timer.Start();
}

Are there better ones?

抠脚大汉 2024-07-16 23:01:53

我发现通用消息总线 。 这是一堂简单的课。

I found Generic Message Bus . It is one simple class.

无妨# 2024-07-16 23:01:53

另一个好的实现可以在以下位置找到:

http: //code.google.com/p/fracture/source/browse/trunk/Squared/Util/EventBus.cs

用例可在以下位置访问:
/trunk/Squared/Util/UtilTests/Tests/EventTests.cs

此实现不需要外部库。

改进可能是能够使用类型而不是字符串进行订阅。

Another good implementation can be found at:

http://code.google.com/p/fracture/source/browse/trunk/Squared/Util/EventBus.cs

Use cases is accessible at:
/trunk/Squared/Util/UtilTests/Tests/EventTests.cs

This implementation does not need external library.

An improvement may be to be able to subscribe with a type and not a string.

无畏 2024-07-16 23:01:53

您应该查看 Ayende 的截屏系列 Hibernating Rhinos 中的第 3 集 - “实施事件代理” ”。

它展示了如何使用 Windsor 来实现一个非常简单的事件代理来连接事物。 还包括源代码。

所提出的事件代理解决方案非常简单,但不需要花费太多时间来增强该解决方案以允许参数与事件一起传递。

You should check out episode 3 in Hibernating Rhinos, Ayende's screen casts series - "Implementing the event broker".

It shows how you can implement a very simple event broker using Windsor to wire things up. Source code is included as well.

The proposed event broker solution is very simple, but it would not take too many hours to augment the solution to allow arguments to be passed along with the events.

爱*していゐ 2024-07-16 23:01:53

我创建了这个:

https://github.com/RemiBou/RemiDDD/tree /master/RemiDDD.Framework/Cqrs

与 ninject 存在依赖关系。
你有一个消息处理器。 如果你想观察一个事件,实现“IObserver”;如果你想处理命令,实现“ICommandHandleer”

I created this :

https://github.com/RemiBou/RemiDDD/tree/master/RemiDDD.Framework/Cqrs

There is a dependancy with ninject.
You got a MessageProcessor. If you want to obsere an event, implement "IObserver" if you want to handle a command implement "ICommandHandleer"

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