.NET 的简单事件总线

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/368265/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 10:50:01  来源:igfitidea点击:

A simple event bus for .NET

.netgenericseventsc#-2.0bus

提问by chikak

I want to make a very simple event bus which will allow any client to subscribe to a particular type of event and when any publisher pushes an event on the bus using EventBus.PushEvent()method only the clients that subscribed to that particular event type will get the event.

我想制作一个非常简单的事件总线,它允许任何客户端订阅特定类型的事件,并且当任何发布者使用EventBus.PushEvent()方法将事件推送到总线上时,只有订阅该特定事件类型的客户端才会获得该事件。

I am using C# and .NET 2.0.

我正在使用 C# 和 .NET 2.0。

采纳答案by chikak

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

我找到了Generic Message Bus。这是一个简单的类。

回答by Sean Kearon

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):

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

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

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

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

维基在这里:https: //github.com/grumpydev/TinyMessenger/wiki

It has a Nuget package also

它也有一个 Nuget 包

Install-Package TinyMessenger

回答by duo

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

另一个,受 EventBus for android 的启发,但要简单得多:

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));

        // ...
    }
}

回答by Volker von Einem

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

您还可以查看 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();
}

Are there better ones?

有更好的吗?

回答by heralight

Another good implementation can be found at:

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

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

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

用例可在以下位置访问:/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.

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

回答by Simon

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

复合应用程序块包括事件代理可能是你有帮助。

回答by remi bourgarel

I created this :

我创建了这个:

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

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"

与ninject 有依赖关系。你有一个 MessageProcessor。如果要观察事件,请实现“IObserver” 如果要处理命令实现“ICommandHandler”

回答by mookid8000

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

您应该查看Hibernating Rhinos 中的第 3 集,Ayende 的屏幕投射系列 - “实现事件代理”。

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

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

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.

提议的事件代理解决方案非常简单,但不会花费太多时间来扩充解决方案以允许参数与事件一起传递。