【问题标题】:What to do when property name matches class name属性名与类名匹配时怎么办
【发布时间】:2013-04-23 19:25:37
【问题描述】:

在我们的 C# 代码中,我们有一个名为 Project 的类。我们的基础 BusinessObject 类(所有业务对象都继承自)定义了一个属性:

public Project Project { get; set; }

只要我们留在 C# 代码库中,这通常不是问题。但是,这些业务对象类通过网络在 Web 服务中公开。一些消费语言(例如 Flex 的动作脚本)无法处理具有与其类同名的属性。

这种命名冲突在我们的代码中无处不在。有时更改属性或类的名称很容易。有时候真的很难。我们绞尽脑汁,想不出一个好的标准方法来处理这个问题。可以将 Project 类重命名为 ProjectType 或 ProjectInfo,但这很丑陋并且破坏了我们所有消费者现有的代码。我们可以保持类型名称不变并将属性名称更改为 ProjectInfo,但这会导致同样的问题。

对于这种情况,有人有任何指导或最佳做法吗?

编辑:

回应给出的一些建议:

  • 方法没有暴露在网络上,所以我们不能使用方法。
  • 我更喜欢标准命名约定,该约定也符合 Microsoft 自己的命名标准。
  • 为 Flex 公开不同的合同可能是一种选择。但是,我们将 Weborb 用于 Flex 互操作。 Weborb 使用反射来精确匹配属性名称,而不是使用 XML 或 SOAP 序列化。如果有人知道更多关于使用 Weborb 进行自定义序列化的信息,那将会很有帮助。

编辑#2:

作为参考,我们最终将属性重命名为:

public Project ProjectInfo { get; set; }

【问题讨论】:

    标签: c# web-services properties


    【解决方案1】:

    如果您已经使用有问题的名称提供了 Web 服务,听起来您遇到了一个棘手的问题。如果您不能在不破坏现有客户的情况下进行任何更改,并且您不能在不破坏 Flex 的情况下保持原样,有人会被破坏。

    可能可能会在不同的 URL 上公开并行 API。我同意 shahkalpesh 关于属性会出现问题的 Get/Set 方法的建议。这样做的好处是您可以一次做出决定,然后保持一致,而无需每次都考虑。这也意味着您可能可以在第一个 API 的基础上自动创建第二个 API。

    【讨论】:

    • 我们的目标是提供一种不会破坏 Flex 的解决方案。我们可以重构 .NET 代码,只是需要一些时间。我希望也许有一个标准的命名约定可以防止这个问题再次发生。
    • 如前所述,方法不会暴露在网络上,因此它们无济于事。公开不同的合同可能是一种选择。但是,我们使用的是 Weborb,它有自己的序列化方案,它使用反射来查找确切的成员名称,而不是使用 xml 序列化。
    • 标准的 .NET 命名约定不会尝试解决这个问题,因为它通常不是问题。听起来您使用的技术并不能胜任工作:(
    【解决方案2】:

    我认为最好的解决方案是重构您的项目,将对象 Project 重命名为 WnProject、ProjectBase 或与项目具体内容相关的其他名称。

    这是您的 API,任何使用它的人都必须了解,可能会发布重大更改,这是依赖外部资源的成本。

    【讨论】:

      【解决方案3】:

      好的旧方法怎么样? (GetProject/SetProject 或 .net 的方式 - Thread.CurrentThread)

      【讨论】:

      • Web 服务代理对象的属性除外,它仅基于元数据:没有方法,只有数据...
      • 是的,方法不会通过网络公开,只有属性和字段。不幸的是,这行不通。
      【解决方案4】:

      我知道这是一个老问题,但它可能对其他人有所帮助。

      为什么不为不支持相同道具名称和类型的消费者提供不同的 WSDL?
      重命名 WSDL 中的复杂类型(不是元素名称!)

      从你现在(应该)拥有的:

      <xs:element name="Project" type="Project"/>
      
      <xs:complexType name="Project">
        <xs:sequence>
          <xs:element name="Title" type="xs:string"/>
          <xs:element name="Description" type="xs:string"/>
        </xs:sequence>
      </xs:complexType>
      

      收件人:

      <xs:element name="Project" type="ProjectType"/>
      
      <xs:complexType name="ProjectType">
        <xs:sequence>
          <xs:element name="Title" type="xs:string"/>
          <xs:element name="Description" type="xs:string"/>
        </xs:sequence>
      </xs:complexType>
      

      在这种情况下,SOAP 消息将保持完全相同,这意味着您不必重新编译解决方案或提供其他服务。
      此外,其他消费者无需进行任何更改。

      【讨论】:

      • 我已经多年没有在 .NET 中使用 Web 服务了!如果内存服务正确,则 WSDL 会自动生成并且无法自定义。是否有允许您自定义自动生成的属性名称的属性?
      • 我没有对此进行测试,但我认为您正在寻找的属性是:msdn.microsoft.com/en-US/library/awac9czf(v=vs.80).aspx 上显示的 System.Xml.Serialization.XmlRootAttribute 或者,您可以禁用显示 WSDL(添加 ? wsdl 到 url) 到消费者 (stackoverflow.com/questions/3477055/…) 并根据消费者技术为他们提供单独的 WSDL。
      • 多年来,我的 .NET 知识已经生疏,但似乎 XmlRootAttribute 用于类型而不是属性。至于提供单独的 WSDL/端点,那将是一个相当繁重的维护负担。我们有许多服务和合同需要维护和公开。在项目的生命周期中,我从未手动接触过 WSDL 文件。
      【解决方案5】:

      虽然它对外部语言没有真正的帮助,但可以给命名空间取别名(假设类 Project 与具有属性 Project 的类位于不同的命名空间中),如下所示:

      using ns = MyProject.Namespace;
      

      那么你只需要这样做:

      var newProject = new ns.Project();
      

      【讨论】:

      • 我真的看不出这与问题有什么关系,因为它与通过 WSDL 公开的对象有关,而不是在他的内部代码中。
      【解决方案6】:

      WTF 是否有一种语言的变量名称与 Web 服务有关?

      必须有人在他们的 XML 绑定中非常懒惰,才能在网络上公开实现细节。

      WSDL/SOA 的全部意义在于您有一个独立于实现的消息规范。如果您从源代码生成消息规范,或者从规范生成源而不考虑生成的对象的变化,那么您最终会得到紧密耦合的系统。这种紧密耦合的一个症状是获得不是合法标识符的变量/属性名称。服务(而不是 RPC)不是紧密耦合的。你不应该改变你的服务实现来满足服务的实现——如果你必须这样做,你的堆栈中的某些东西就坏了。这适用于成员变量/属性以及方法。

      【讨论】:

      • 谁提到了变量?类/属性名称构成基于 WSDL 的 Web 服务的元数据的一部分。选择的名称是有效的(如果不幸的话) - 如果有什么弹性活页夹不合格......
      • 成员变量是“属性”的另一个术语
      猜你喜欢
      • 1970-01-01
      • 2011-11-08
      • 2014-09-28
      • 2013-02-13
      • 2015-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-14
      相关资源
      最近更新 更多