我已经创建了一个简单的消息总线,用于排队和发布/发出事件。
我正在使用 StructureMap 来定位事件的注册处理程序 (Action<T>
),但我不确定如何将其从 StructureMap 返回的对象转换为可调用的操作。
由于我无法将其转换为 Action<object>
,因此我假设 Action<T>
不是协变的?是否有其他方法可以完成这个任务?
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?
}
}
}
}
IHandle<in T>
,但它不允许我向下转换为IHandle<object>
。 - Ben FosterDynamicInvoke
,它可以工作,但我读到它比Invoke
的开销更大。我想另一个选择是将事件的处理排队,这样我就可以避免任何类型转换问题,例如queue.Enqueue(() => Handle<TEvent>(e))
。 - Ben FosterDynamicInvoke
会有相当大的开销 - 但是性能对你来说有多大问题?不过,你接受的答案似乎很好。 - Jon Skeet