代码之家  ›  专栏  ›  技术社区  ›  CodeChef

如何在WCF中一般地执行服务操作?

  •  2
  • CodeChef  · 技术社区  · 15 年前

    我正在寻找一种方法来完成下面的源代码中描述的行为。我已经使用“始终生成消息协定”选项创建了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,它会自动神奇地工作。

    2 回复  |  直到 12 年前
        1
  •  2
  •   marc_s Anurag    15 年前

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

    很多程序员错误地认为wcf是某种.NET远程处理——例如,他们认为你基本上是在一个很远的服务器上接触一个远程对象,在某个地方调用一个“远程的.NET对象”的方法。绝对不是这样!

    WCF是关于 消息传递 -您的客户机和服务器只交换 序列化消息 (可能还有标题)-就是这样。

    也就是说:这些消息交换机制被设计成与很多非.NET平台互操作。它们利用WSDL和XSD机制交换操作描述(WSDL)和正在交换的数据结构(XSD)。

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

    因此,最后,您真正需要理解和编程的是WSDL/XSD定义的标准——因此,您需要忘记所有.NET细节,如泛型、接口和实现这些接口的类,这些都非常快。它们只是不在WCF消息基础设施上工作。

    在WCF客户机和WCF服务器之间所能交换的只是您可以在XML模式中描述和表示的任何内容——具体类型由基本数据类型(如字符串、整数等)组成。XSD支持一点继承,但它不知道泛型的用途,而且它根本不处理接口和非具体类。

    因此,开箱即用,我不认为你的方法有一个通用接口和实现该接口的消息,以及WCF计算出基于该类调用什么真正的方法。这并不是WCF的架构和设计方式。

    您可能能够创建一个自定义(但具体)的基类,并且您可能能够扩展服务器端的WCF操作调度器,根据您的类被传入(或为骑乘而来的头中的一些额外信息),调用不同的方法,但我认为这既不容易,也不是WCF打算采用的方式RK-不保证你真的能成功。

        2
  •  0
  •   CodeChef    15 年前

    下面是我如何解决这个问题。我的消息契约,实现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));
        }
    }
    
    推荐文章