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

问题描述 投票:0回答:1

我目前在我当前的项目中无法实现对象间通信的解决方案。我决定尝试使用像中介者模式这样的对象,在该对象中,对象通过广播向中介者使用消息相互通信。然后,调解器将消息发送到专门侦听正在广播的消息的对象。

我以前使用的先前的调解器对象依赖于将容器保存到仅处理基本消息的处理程序中,从而迫使侦听器在对其进行处理之前强制转换消息。我以为我可以通过根据某种任意类型将处理程序本身的集合放入一个键控集合中来实现。通过这样做,我希望避免任何类型的侦听器都必须响应消息。

问题是,我似乎无法遵循如何获得一个对象,该对象可以让其他人注册一个强类型的消息,以维护各种不同类型的强类型消息处理程序的单个集合。

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

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));
     }
}

这种设计是否可能具有我想要的强类型消息处理?如果是这样,我该怎么办?

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

c# generics design-patterns mediator
1个回答
0
投票

可能最好的方法是查看Mediatr如何实现该模式,因为它是Mediator模式/应用程序消息传递中最受欢迎的C#库。

https://github.com/jbogard/MediatR/blob/master/src/MediatR/Mediator.cs

简而言之,它包含“ NotificationHandlerWrapperImpl”的包装对象的列表。但是它将它们保存在对象列表中(这样您就可以解决Action vs Action vs Action Casting问题)。

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/

© www.soinside.com 2019 - 2024. All rights reserved.