如何存储参数化方法的类型参数,然后使用它们将JSON对象转换为泛型类型的普通对象?

我正在尝试为Delphi和.NET编写通用的消息传递系统.系统允许将消息定义为普通对象,并将消息处理程序定义为对这些对象起作用的匿名方法.

对象将转换为JSON,并在同一台计算机上运行的应用程序之间传递.每个应用程序都维护一个理解特定消息类型的处理程序列表.

我的类有许多参数注册方法.有些采用单一类型参数.有些参数采用一对参数,其中一个表示请求对象,另一个表示响应对象.以下是请求/响应处理程序注册内容

procedure TTelegraph.RegisterRequestHandler<TRequest,TResponse>
  (requestTypetoHandle: string; handler: TFunc<TRequest,TResponse>);
begin
  FRequestHandlers.Add(requestTypetoHandle,TRequestHandler<TRequest,TResponse>.Create(handler,TRequest,TResponse));
end;

FRequestHandlers是一个TDictionary< string,TRequestHandler>.注册方法如下调用

FTelegraph.RegisterRequestHandler<TTestRequest,TTestResponse>('My Request',function(x: TTestRequest): TTestResponse
    begin
      Result := TTestResponse.Create;
      Result.Number := x.Number;
      Result.Message := Format('Received: %s',[x.Message]);
    end);

通用TRequestHandler< T1,T2>是一个DTO,它包含处理程序以及TRequest和TResponse类型.它继承自非通用的TRequestHandler.我不确定是否有更好的方法可以解决这个问题,但这是我能想到的在单个集合中存储多个不相关类型的唯一方法.

这一切似乎都很好.问题是收到请求消息时.处理请求消息的C#代码如下所示:

private void ProcessRequestTelegram(Telegram request)
{
    var requestType = _RequestHandlers[request.MessageType].RequestType;
    var typedRequest = JsonConvert.DeserializeObject(request.Payload,requestType);
    var result = _RequestHandlers[request.MessageType].Handler.DynamicInvoke(typedRequest);
    var jsonPayload = JsonConvert.SerializeObject(result);
    var response = new Telegram()
    {
        Payload = jsonPayload,CorrelationID = request.CorrelationID,Template = TelegramTemplateEnum.Response,SenderWindowHandle = _LocalWindowHandle.ToInt32(),RecipientwindowHandle = _MessageRecipient.ToInt32(),MessageType = request.MessageType
    };
    var jsonResponse = JsonConvert.SerializeObject(response);

    var resultCode = _Messaging.SendMessage(_MessageRecipient,jsonResponse);
    CheckIfSendMessageErrorOccurred(resultCode);
}

在上面的代码中,RequestType属于Type类型.

但对于我的生活,我无法想出Delphi的等价物.我试图反序列化request.Payload,我坚持如何传递JSON解析器类型转换有效负载.我已经尝试了各种方法在TRequestHandler的RequestType和ResponseType属性中存储TRequest和TResponse:TTypeInfo,TRTTIType和当前的TClass.但似乎没有任何东西可以传递给TJson.JsonToObject.它有一个泛型重载,它接受返回类型的类型参数,但显然你不能使用TClass作为类型参数.

解决方法

你不能使用TJson.JsonToObject< T>因为在调用它时你没有通用的T.看看这个方法代码,你会看到T被传递给TJSONUnMarshal.CreateObject.因此,在您的情况下,您应该存储TRequest和TResponse的TClass并编写自己的TJson.JsonToObject版本,该版本将传递给TClass.

另一种方法是首先创建实例,然后将其传递给非泛型TJson.JsonToObject,它接受传递的实例的Classtype并将其传递给TJSONUnMarshal.CreateObject.

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...