代码之家  ›  专栏  ›  技术社区  ›  Bob Moore

WCF类型冲突

  •  1
  • Bob Moore  · 技术社区  · 15 年前

    我对WCF有问题。我想我明白问题所在,但我需要 测试这种理解,并询问是否有人以前见过这种情况,或者是否可以提出建议。 一种变通方法或替代方法。请忍受我:这是一个相当大的 很难分解为最小测试用例的问题。

    问题:我正在写一个C接口到一个传统的消息传递系统。我有 实现了直接接口的互操作程序集,所有操作都正常。这个 它的基础是我为每个消息类型都有一个类,以及一个泛型类 对于传递的消息,它只占用与最大大小消息相同的空间。

    每个消息类实现强制转换运算符以强制转换 通用类,称为qod_message。泛型类和单个消息 类都是从无正文的最小消息类派生的。客户C应用程序 要发送消息,只需调用接口程序集中的send方法, 接收Qod_消息,强制转换为用于发送的通用类型。接收器事件 传递接收C应用程序A通用类型,该类型根据通用类型 与消息类型具有一对一关系的成员。

    我已经实现了本地直接接口组装,这一切都正常工作 现在我可以在C测试应用程序和现有的本地遗产之间传递消息 应用。精彩的。基本类结构如下:

    public class QOD_Message_Minimal
    {
       a message header
    }
    
    public class QOD_Message : QOD_Message_Minimal
    {
       generic message - defines an empty body
    }
    
    public class QOD_WcfDialout : QOD_Message_Minimal
    {
       ... some irrelevant code
    
       // cast operators to convert to and from the abstract message class.
    
       public static implicit operator QOD_Message (QOD_WcfDialout m)
       {
          ... some irrelevant code
       }
    
       public static implicit operator QOD_WcfDialout (QOD_Message m)
       {
          ... some irrelevant code
       }
    }
    

    注意演员表。

    现在问题来了。我想扩展这个接口来支持WCF,所以 另一组海外开发人员可以通过WCF与适配器进行通信。 我写的WCF服务。这就是所谓的,令人钦佩的是 想象,wcf_适配器。WCF_适配器为测试目的公开 旧代码。这也很好,通过调用我的 正在将wcf_客户端应用程序转换为旧消息并发送到 (固定)收件人。

    所以我尝试扩展接口来添加一个入口点,它将接受 Qod_消息(调度),希望这与Direct的工作方式相同 接口,即发送方将其消息转换为Qod_消息,调用 这种类型的发送函数和适配器将简单地传递 在其本地接口程序集中接收到通用消息 派遣。因此,wcf代码看起来非常像正常的消息传递 代码。

    [ServiceContract]
    public interface IDialout
    {
       [OperationContract (IsOneWay = true)]
       void Dialout (string NumberToDial);
    
       [OperationContract (IsOneWay = true)]
       void Dispatch (QOD_Message msg);
    }
    

    所以我扩展了客户机和wcf_适配器服务,生成 我的WCF客户端代理代码和…哦。客户端不会编译。

    客户端应用程序似乎无法理解cast运算符,并抛出 编译错误。即使我在上面的代码中包含消息传递程序集 作为引用,客户端代码“首选”在生成的 代理并忽略原始消息类型,因此它无法“查看”强制转换和 无法编译。这是错误:

    警告CS0436: “blah blah\generatedproxy.cs”中的类型“qod-messaging.qod-message” 与中导入的类型“qod-messaging.qod-message”冲突 'blah blah\qod_messaging.dll'。使用“blah blah\generatedproxy.cs”中定义的类型。

    据我所知,生成的代理中定义的类是正确的, 当然,生成的代理类只定义数据成员,而不是功能。 有两个班

    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute(Name="QOD_Message_Minimal", Namespace="http://schemas.datacontract.org/2004/07/QOD_Messaging")]
    [System.Runtime.Serialization.KnownTypeAttribute(typeof(QOD_Messaging.QOD_Message))]
    public partial class QOD_Message_Minimal : object, System.Runtime.Serialization.IExtensibleDataObject
    {
       whole slew of data members.
    }
    
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute(Name="QOD_Message", Namespace="http://schemas.datacontract.org/2004/07/QOD_Messaging")]
    public partial class QOD_Message : QOD_Messaging.QOD_Message_Minimal
    {
       extra stuff to define the added body.
    }
    

    所以…

    我可以去掉程序集引用,这样代码就看不到强制转换而失败 编译,或者我可以将引用保留在中,编译器故意忽略 程序集的类型定义并使用代理定义…无法编译。

    其他WCF开发人员以前见过这种情况吗?还是每个人都坚持 调用wcf端点时是否使用简单值参数?我只需要 为每种类型的消息i声明具有唯一类参数的端点 可能要发送?这是维护的噩梦。

    2 回复  |  直到 9 年前
        1
  •  1
  •   Marc Gravell    15 年前

    转换运算符不是生成的MEX的一部分,因此它们不会存在于客户端。

    考虑到这里的复杂性,是否可以使用程序集共享?即,不是生成的(代理)类型,您可以引用类型的原始程序集吗?这在IDE(在高级对话框上,虽然在默认情况下似乎是启用的,但是如果您引用了具有消息类型的程序集)和通过svcutil(/r开关)都受支持。然后在客户机上有您的原始类型,包括转换。

    如果您想保留代理方法,您可以为每条消息添加部分类,并在其中添加额外的转换——但这有明显的维护成本。

        2
  •  1
  •   John Saunders    9 年前

    在Web服务中唯一可以公开的类成员是方法。属性、运算符、强制转换、索引器、委托、事件或任何其他内容都不能公开。

    回想一下,有一种方式或另一种方式,Web服务是由一个或多个XML文档描述的:WSDL、XML模式、WS-Policy等。这些文档都没有一种方式来描述任何类型的编程语言操作符,包括cast操作符。

    可以将类方法公开为Web服务运算符,也可以将类公开为数据协定或故障协定,公开为XML模式,将消息协定公开为消息类型。没有其他东西可以暴露。