A simple event bus for .NET [closed]

限于喜欢 提交于 2019-12-20 09:03:10

问题


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.

I am using C# and .NET 2.0.


回答1:


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



回答2:


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

        // ...
    }
}



回答3:


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?




回答4:


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




回答5:


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




回答6:


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.




回答7:


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.




回答8:


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"



来源:https://stackoverflow.com/questions/368265/a-simple-event-bus-for-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!