在运行时通过接口动态将委托强制转换/包装为签名

时间:2018-08-21 07:40:21

标签: c# reflection casting delegates .net-core

上下文

当前,我正在使用.NET Core创建用C#编写的提取,转换和加载(ETL)应用程序。 ETL应用程序的源代码是Soap Web服务,其中包含多种方法。每个实体(员工,公司等)和检索方式(ByKey,ByQuery等)都有自己的Soap Web服务方法。例如,如果我要通过执行查询来检索实体“ Employee”,则将调用GetEmployeeByQuery方法。所有方法都返回带有XML的字符串。

Visual Studio通过其WSDL文件(通过dotnet-svcutil间接生成)生成了该Web服务的代理类。不幸的是,为该服务生成的代理类似乎是根据消息契约模式生成的。这意味着代理方法GetEmployeeByQuery返回GetEmployeeByQueryResponse子类,该子类具有包含Body子类的字段GetEmployeesByQueryResponseBody。实际结果位于GetEmployeeByQueryResponseBody名称为GetEmployeeByQueryResult的字符串字段中。

理想地,ETL应用程序能够通过反射并在应用程序配置的基础上调用Soap Webservice方法。该配置包含要调用的方法和参数,并且通过某些工厂,这将导致一个Delegate,该Delegate将用作应用程序中其他位置的策略。此委托应该是通用的,不应与任何特定实体绑定。

问题

当前,我创建了一个带有签名的委托,该委托仅由具体的类型实现组成。这是必需的,因为Delegate.CreateDelegate方法需要这样做才能将实际方法绑定到委托。签名为Func<string, string, string, string, Task<GetEmployeeByQueryResponse>>。但是,此签名与特定实体相关联,这就是我要防止的实体。

因此,我试图将此委托转换为签名Func<string, string, string, string, Task<IMessageResult<string>>>,其中IMessageResult<string>是通过子类在生成的代理代码上实现的接口。

尝试检索更多通用委托的方法

public static TMethodSignatureInterfaced GetMethodDelegate<TMethodSignatureInterfaced>(object classInstance, string methodName, Type methodSignatureTyped)
    where TMethodSignatureInterfaced : class
{
    //Another way of casting, same result.
    //TMethodSignatureInterfaced method = (TMethodSignatureInterfaced)(object)Delegate
    //    .CreateDelegate(methodSignatureTyped, classInstance, methodName) as TMethodSignatureInterfaced;

    TMethodSignatureInterfaced method = Delegate
        .CreateDelegate(methodSignatureTyped, classInstance, methodName) as TMethodSignatureInterfaced;

    if (method == null)
        throw new InvalidCastException($"Method {methodName} could not be cast into a delegate. The given method signature could not be found.");

    return method;
}

不幸的是,似乎不可能将委托强制转换为另一个签名。该代码要么抛出错误(使用第一种转换技术),要么返回null。在其他帖子中,我看到了interface is specified casting a delegate is possible的情况。我想知道是否有人会解决这个问题。

编辑

this Stackoverflow问题中,我发现Task类是不变的。如果我正确理解它,那么我将目标直接投射到另一个签名的目标就变得不可能了。那里提到的解决方法似乎与我的具体情况无关。我将对此进行进一步研究,仍然非常感谢您的帮助。

0 个答案:

没有答案