如何将对象投射到Action< T> [英] How to cast object to Action<T>

查看:37
本文介绍了如何将对象投射到Action< T>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了一个简单的消息总线,它可以排队并发出/发布事件.

I've created a simple message bus that queues and emits/publishes events.

我正在使用StructureMap定位事件的注册处理程序( Action< T> ),但不确定如何将其从StructureMap返回的对象强制转换为可调用的操作.

I'm using StructureMap to locate the registered handlers (Action<T>) of the event but am not sure how to cast it from the object that StructureMap returns into an invoke-able action.

因为我无法转换为 Action< object> ,所以我假设 Action< T> 不是协变的?可以用另一种方式吗?

Since I can't cast to Action<object> I'm assuming that Action<T> is not covariant? Can this be done another way?

public class Bus
{
    private ConcurrentQueue<object> events = new ConcurrentQueue<object>();
    public void Queue<TEvent>(TEvent e)
    {
        events.Enqueue(e);
    }

    public void Emit()
    {
        object e;
        while (events.TryDequeue(out e))
        {
            var handlerType = typeof(Action<>).MakeGenericType(e.GetType());
            foreach (var handler in ObjectFactory.GetAllInstances(handlerType))
            {
                // how to invoke action?
            }
        }
    }
}

推荐答案

如果在您的 Queue 方法内部,您不将事件排队,而是将发出事件的代码排队?

What if inside your Queue method you'd queue not events but rather the code which emits them?

private ConcurrentQueue<Action> handlers = new ConcurrentQueue<Action>();
public void Queue<TEvent>(TEvent e)
{
    handlers.Enqueue(new Action(() =>
    {
        foreach (var handler in GetHandlers<TEvent>())
        {
            handler(e);
        }    
    }));
}

public void Emit()
{
    Action act;
    while (handlers.TryDequeue(out act))
    {
        act();
    }
}

private IEnumerable<Action<TEvent>> GetHandlers<TEvent>()
{
    return ObjectFactory.GetAllInstances(typeof(Action<TEvent>>));
}

希望这会有所帮助.

这篇关于如何将对象投射到Action&lt; T&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆