通用事件处理

时间:2012-01-07 23:07:55

标签: c# .net

我正在使用一些允许注册Action<IMessage>类型的事件处理程序的.NET框架。

IMessage是收到的所有消息正在实现的接口。

我希望能够(以某种方式)注册知道收到的具体消息类型的处理程序,以便更彻底地记录它。

类似的东西:

manager.Register(SpecialHandler);

public void SpecialHandler(SpecialMessage msg)
{
   // log.
}
  • SpecialMessage是一种实现IMessage的类型。

这是不可能的,有一种简单的方法吗?

4 个答案:

答案 0 :(得分:3)

// improved version of Travis Gockel's approach
void Register<T>(Action<T> action, bool invokeOnTypeMismatch = false)
    where T : IMessage
{
    Action<IMessage> wrapped = (msg) =>
        {
            if (msg is T)
            {
                action((T)msg);
            }
            else if (invokeOnTypeMismatch)
            {
                action(default(T));
            }
        };

    // private Action<IMessage> method = delegate{};
    method += wrapped;
}

答案 1 :(得分:2)

class MessageSystem
{
    readonly Dictionary<Type, Action<IMessage>> handlers = new Dictionary<Type, Action<IMessage>>();

    public void Register<T>(Action<T> action) where T : IMessage
    {
        Action<IMessage> wrapped = (IMessage msg) => action((T)msg);
        handlers[typeof(T)] = wrapped;
    }

    public void Invoke(IMessage msg)
    {
        handlers[msg.GetType()](msg);
    }
}

答案 2 :(得分:1)

你可以在这里使用多态

元代码:

interface IMessage 
{
    void Handle()
    ... 
}

class MessageFoo : IMessage
{
    void Handle()
    {
        //foo handle
    }
}

class MessageBar : IMessage
{
    void Handle()
    {
        //bar handle
    }
}

这就是你处理它们的地方

class HandlingManager
{
    void HandleMessage(IMessage m)
    {
        m.Handle(); //knows which concrete type
    }
}

答案 3 :(得分:0)

查看CSharpMessenger Extended

  

这是一个基于委托的C#事件系统。它使用泛型来实现静态类型。与其他消息传递系统(如CSharpEventManager)一样,它允许事件生成器和事件使用者之间的消息传递,而不需要生产者或消费者彼此了解。信使被实现为静态类,因此永远不需要实例化Messenger对象。泛型的使用意味着参数可以是任何类型,并且不限于特殊Message类的子类 - 如果回调只需要一个浮点数,那么为它提供一个浮点数。