【问题标题】:How to generically execute service operations in WCF?如何在 WCF 中通用地执行服务操作?
【发布时间】:2010-01-10 18:20:21
【问题描述】:

我正在寻找一种方法来完成下面源代码中所示的行为。我使用“始终生成消息合同”选项创建了 WCF 服务代理。我所有的请求和响应消息合约都实现了一个通用接口,我想使用相同的函数来执行它们。在我看来,应该有一种通过客户端代理发送消息的通用方式,但我在任何地方都找不到。任何帮助将不胜感激!

// I can do this
private IPagedResponse GetAllFoods()
{
    NutrientDBClient client = new NutrientDBClient();
    GetAllFoodsRequest request = new GetAllFoodsRequest();
    GetAllFoodsResponse response = client.GetAllFoods(request);

    return response;
}
// I'd like to do this
private IPagedResponse ExecutePagedRequest(IPagedRequest request)
{
    NutrientDBClient client = new NutrientDBClient();
    IPagedResponse response = (IPagedResponse)client.Execute(request);

    return response;
}

我目前已经在 NutrientDBClient 中添加了一个 ExecutePagedRequest(IPagedRequest) 方法,并根据 IPagedRequest 的具体类型手动执行正确的服务操作。我正在寻找一种更优雅的方式,以便我可以在消息合约上简单地实现 IPagedRequest 并且它会自动神奇地工作。

【问题讨论】:

    标签: wcf messagecontract


    【解决方案1】:

    不是 100% 确定您真正想要实现什么,但让我解释一下有关 WCF 的一些基础知识。

    许多程序员错误地将 WCF 视为某种 .NET 远程处理 - 例如。他们认为您基本上是在访问远处服务器上的远程对象,在某处调用“远程”.NET 对象上的方法。绝对不是这样的!

    WCF 是关于 messaging - 您的客户端和服务器只交换 序列化消息(可能还有标头) - 仅此而已。

    也就是说:这些消息交换机制旨在与许多非 .NET 平台(Java、Ruby)互操作。它们利用 WSDL 和 XSD 机制来交换操作描述 (WSDL) 和正在交换的数据结构 (XSD)。

    WSDL 和 XSD 都是关于定义良好的显式调用和数据结构。这些标准提供的功能是所有 SOA 平台之间的最低公分母 - 因此,它比您可能已经习惯使用纯 .NET 的功能更受限制。 SOA 世界和 OOP 世界并不总是很匹配。

    所以最后,您真正需要理解和编程的是 WSDL/XSD 定义的标准 - 因此,您需要忘记所有 .NET 细节,如泛型、接口和实现这些接口的类真的很快。它们根本无法在 WCF 消息传递基础架构上工作。

    您可以在 WCF 客户端和 WCF 服务器之间交换的所有内容都是您可以在 XML 架构中描述和表达的任何内容 - 由字符串、整数等基本数据类型组成的具体类型。 XSD支持一点继承,但是对泛型一窍不通,根本不处理接口和非具体类。

    所以开箱即用,我不认为您使用通用接口和实现该接口的消息和 WCF 确定基于该类调用的真正方法的方法会奏效。这不是 WCF 的架构和设计方式。

    您可能能够创建一个自定义(但具体的)基类,并且您可能能够在服务器端扩展 WCF 操作调度程序,以根据传入的类(或一些额外的信息)调用不同的方法标题随之而来) - 但我认为这并不容易,也不是 WCF 的工作方式 - 不能保证你真的能够成功。

    【讨论】:

    • 感谢马克深思熟虑的回答。我真的只是想扩展 Visual Studio (svcutil.exe) 为我生成的客户端代理。为我生成代码的消息合同类是部分类。这意味着我可以将纯粹的客户端成员附加到客户端代理类中,以使它们符合通用接口。那时,我想编写客户端函数来处理这些消息,因为它们具有相似的行为 -> 分页结果。我想我正在寻找的是可以根据消息类型路由消息的客户端?
    • 好的,我明白您在寻找什么,但我认为 WCF 在这方面没有什么可提供的。您必须使用通用接口在客户端代理之上创建自己的层,然后根据传入的消息类型调用几个特定的​​ WCF 客户端代理方法之一。可行,但是WCF 在这里不提供任何支持...
    • 是的,这就是我所发现的。我看的越多,除了 MessageContract 属性之外,代码生成的消息合约提供很少的元数据来帮助路由消息。我很快就会在此处发布我的解决方案,以供未来的读者阅读。
    【解决方案2】:

    以下是我解决此问题的方法。我的消息合同,实现 IPagedRequest 和 IPagedResponse。 NutrientDBClient 是我的代码生成客户端代理 (ClientBase)。 ExecutePagedRequest() 根据请求的具体类型进行消息路由。

    public interface IPagedRequest
    {
        PagingContext PageInfoState { get; set; }
    }
    
    public interface IPagedResponse
    {
        PagingContext PageInfoState { get; }
        IEnumerable ResultItems { get; }
    }
    
    public partial class NutrientDBClient : IHasPagedServiceOperations
    {
        public IPagedResponse ExecutePagedRequest(IPagedRequest request)
        {
            if (request == null) { throw new ArgumentNullException("request"); }
    
            if (typeof(GetAllFoodsRequest).IsAssignableFrom(request.GetType()))
            {
                return GetAllFoods((GetAllFoodsRequest)request);
            }
    
            // Other Service Operations that take IPagedRequest and 
            // return IPagedResponse removed for example
    
    
            throw new NotSupportedException(
                string.Format("Paged requests of type {0} are not supported.",
                    request.GetType().Name));
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多