C# C中中介中的强类型消息处理程序#

C# C中中介中的强类型消息处理程序#,c#,generics,design-patterns,mediator,C#,Generics,Design Patterns,Mediator,我目前在当前项目中实现对象间通信解决方案时遇到问题。我决定尝试一种类似中介模式的对象,其中对象通过向中介的广播使用消息相互通信。然后,中介器将消息发送给专门侦听了正在广播的消息的对象 我以前使用的中介对象依赖于将容器保存到只处理基本消息的处理程序,强制侦听器在处理消息之前强制转换消息。我想我可以通过在一个键控集合中根据某种任意类型设置处理程序集合来解决这个问题。通过这样做,我希望避免听众为了回应信息而必须做的任何类型的选择 问题是,我似乎无法理解如何获取一个允许其他人注册强类型消息以维护不同类型

我目前在当前项目中实现对象间通信解决方案时遇到问题。我决定尝试一种类似中介模式的对象,其中对象通过向中介的广播使用消息相互通信。然后,中介器将消息发送给专门侦听了正在广播的消息的对象

我以前使用的中介对象依赖于将容器保存到只处理基本消息的处理程序,强制侦听器在处理消息之前强制转换消息。我想我可以通过在一个键控集合中根据某种任意类型设置处理程序集合来解决这个问题。通过这样做,我希望避免听众为了回应信息而必须做的任何类型的选择

问题是,我似乎无法理解如何获取一个允许其他人注册强类型消息以维护不同类型的强类型消息处理程序的单个集合的对象

理想情况下,我希望面向公众的界面如下所示:

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));
     }
}
类中介
{
私有字典处理程序;//如何保留强类型处理程序
public void RegisterForBroadcast(操作处理程序),其中T:IMessage
{
//如何将强类型处理程序转换为我可以使用的东西?
}
public void UnregisterFromBroadcast(操作处理程序),其中T:IMessage
{
}
公共无效广播(T消息),其中T:IMessage
{
//如何从存储的位置获取并使用处理程序集合?
}
}
类接收器
{
私人调解人;
公共接管人()
{ 
mediator=GetMediator();
RegisterForBroadcast(MessageHandler);
}
私有void MessageHandler(SpecificMessage msg)
{
CustomData=msg.GetCustomData();
}
}
类广播对象
{
私人调解人;
专用数据;
公共广播对象()
{
mediator=GetMediator();
specificData=GetSpecificData();
}
公共无效时间广播()
{
调解人.广播(新的具体信息(具体数据));
}
}
这种设计是否可以实现我想要的强类型消息处理?如果是,我该怎么做


编辑-添加代码来描述我希望发送方和接收方对象如何与方法交互

最好的方法可能是看看Mediatr是如何实现该模式的,因为它是最流行的中介模式/应用内消息传递的C#库

简而言之,它包含“NotificationHandlerWrapperImpl”的包装器对象列表。但它将它们保存在一个对象列表中(这样您就可以绕过动作与动作与动作投射的问题)

私有静态只读ConcurrentDictionary\u requestHandlers=new ConcurrentDictionary();
该包装器的实际实现相当简单:

它基本上使用服务定位器模式来获取IHandler的实例:

var handlers = serviceFactory
    .GetInstances<INotificationHandler<TNotification>>()
    .Select(x => new Func<INotification, CancellationToken, Task>((theNotification, theToken) => x.Handle((TNotification)theNotification, theToken)));
var handlers=serviceFactory
.GetInstances()
.选择(x=>newfunc((通知,theToken)=>x.Handle((通知,theNotification,theToken));

Mediatr实际上非常简单,如果您想挑选和挖掘一些代码来构建自己的代码,我强烈建议您下载源代码。否则,只需使用Mediatr本身,因为在大多数情况下,它就足够了,您不需要自己动手!此处启动和运行的快速指南:

如果您希望注册的处理程序保留在一个集合/映射中,则需要将它们转换为一些常用类型,以便在使用时保存和转换。提供更多您想要做的代码。我添加了一个接收对象和发送对象的示例。如果你想要更具体的东西,我想我需要一个比你给出的更具体的要求。
var handlers = serviceFactory
    .GetInstances<INotificationHandler<TNotification>>()
    .Select(x => new Func<INotification, CancellationToken, Task>((theNotification, theToken) => x.Handle((TNotification)theNotification, theToken)));