代码之家  ›  专栏  ›  技术社区  ›  chikak

一辆简单的活动巴士。NET[关闭]

  •  24
  • chikak  · 技术社区  · 17 年前

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

    我正在使用C#。NET 2.0。

    8 回复  |  直到 13 年前
        1
  •  25
  •   Sean Kearon    6 年前

    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
    
        2
  •  9
  •   duo    11 年前

    另一个灵感来自安卓版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));
    
            // ...
        }
    }
    
        3
  •  2
  •   Simon    17 年前

    这个 Composite Application Block 包含一个可能对您有用的事件代理。

        4
  •  2
  •   Volker von Einem    16 年前

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

    有更好的吗?

        5
  •  2
  •   Peter Mortensen Pieter Jan Bonestroo    13 年前

    我发现了 Generic Message Bus 这是一门简单的课。

        6
  •  1
  •   heralight    15 年前

    另一个良好的实施方式可以在以下网址找到:

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

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

    此实现不需要外部库。

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

        7
  •  0
  •   mookid8000    17 年前

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

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

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

        8
  •  0
  •   remi bourgarel    12 年前

    我创建了这个:

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

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