[英]Strongly-typed Message Handlers in Mediator in C#
我目前在当前项目中实施对象间通信解决方案时遇到问题。 我决定尝试像中介者模式这样的对象,在这种模式下,对象通过向中介者广播的方式使用消息相互通信。 然后,中介将消息发送给专门监听正在广播的消息的对象。
我以前使用过的中介器对象依赖于将容器保存到处理程序只处理基本消息,迫使侦听器在处理消息之前强制转换消息。 我认为我可以通过根据某种任意类型将处理程序本身放在一个键控集合中来解决这个问题。 通过这样做,我希望避免听众必须做的任何类型的转换来响应消息。
问题是,我似乎无法理解如何获取允许其他人注册强类型消息以维护不同类型强类型消息处理程序的单个集合的对象。
理想情况下,我希望面向公众的界面如下所示:
class Mediator
{
private Dictionary<Type, ???> handlers; // how to I retain the strongly-typed handler
public void RegisterForBroadcast<T>(Action<T> handler) where T : IMessage
{
// how can I turn the strongly-typed handler into something I can use?
}
public void UnregisterFromBroadcast<T>(Action<T> handler) where T : IMessage
{
}
public void Broadcast<T>(T message) where T : IMessage
{
// how do I get the collection of handlers from where it's stored and use it?
}
}
class Receiver
{
private Mediator mediator;
public Receiver()
{
mediator = GetMediator();
mediator.RegisterForBroadcast<SpecificMessage>(MessageHandler);
}
private void MessageHandler(SpecificMessage msg)
{
CustomData data = msg.GetCustomData();
}
}
class BroadcastingObject
{
private Mediator mediator;
private SpecificData data;
public BroadcastingObject()
{
mediator = GetMediator();
specificData = GetSpecificData();
}
public void TimeToBroadcast()
{
mediator.Broadcast<SpecificMessage>(new SpecificMessage(specificData));
}
}
这种设计是否有可能实现我想要的强类型消息处理? 如果是这样,我该怎么做?
编辑 - 添加了代码来描述我希望发送方和接收方对象如何与方法交互。
可能最好的方法是查看 Mediatr 如何实现该模式,因为它是 Mediator 模式/应用程序消息传递中最流行的 C# 库。
https://github.com/jbogard/MediatR/blob/master/src/MediatR/Mediator.cs
简而言之,它包含“NotificationHandlerWrapperImpl”的包装对象列表。 但是它将它们保存在一个对象列表中(这样你就可以解决 Action vs Action vs Action 转换问题)。
private static readonly ConcurrentDictionary<Type, object> _requestHandlers = new ConcurrentDictionary<Type, object>();
该包装器的实际实现相当简单: https : //github.com/jbogard/MediatR/blob/e8833143c0742bdf72a6c6f104ef1dfadb59bf42/src/MediatR/Internal/NotificationHandlerWrapper.cs
它基本上使用服务定位器模式来获取 IHandler 的实例:
var handlers = serviceFactory
.GetInstances<INotificationHandler<TNotification>>()
.Select(x => new Func<INotification, CancellationToken, Task>((theNotification, theToken) => x.Handle((TNotification)theNotification, theToken)));
Mediatr 实际上非常简单,如果您想挑选并制作自己的代码,我强烈建议您下载源代码。 否则,在大多数情况下,只需使用 Mediatr 本身就足够了,您无需自己动手! 在此处启动和运行的快速指南: https : //dotnetcoretutorials.com/2019/04/30/the-mediator-pattern-part-3-mediatr-library/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.