代码之家  ›  专栏  ›  技术社区  ›  Lucas B

为WCF保留抽象方法服务器端的方法

  •  1
  • Lucas B  · 技术社区  · 15 年前

    我们正在强制所有域对象实现GetHashCode。

    namespace Core
    {
      [Serializable]
      public abstract class DomainObject
      {
        public abstract override int GetHashCode();
      }
    }
    
    namespace Entity.Domain
    {
      [Serializable]
      [DataContract]
      public partial class IdCard : DomainObject
      {
        private System.Int32 _effDte;
    
        [DataMember]
        public virtual System.Int32 EffDte
        {
            get { return _effDte; }
            set { _effDte = value; }
        }
    
        public override int GetHashCode()
        {
            return EffDte.GetHashCode();
        }
      }
    }
    

    当我们通过wcf公开这些域对象时,以下生成的服务需要进行更新后修改才能编译。

    //------------------------------------------------------------------------------
    // <auto-generated>
    //     This code was generated by a tool.
    //     Runtime Version:2.0.50727.3053
    //
    //     Changes to this file may cause incorrect behavior and will be lost if
    //     the code is regenerated.
    // </auto-generated>
    //------------------------------------------------------------------------------
    
    namespace IdCardManagerServiceReference {
    using System.Runtime.Serialization;
    using System;
    
    
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute(Name="IdCard", Namespace="http://schemas.datacontract.org/2004/07/Entity.Domain")]
    [System.SerializableAttribute()]
    public partial class IdCard : Core.DomainObject, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged { 
        [System.NonSerializedAttribute()]
        private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
    
        [System.Runtime.Serialization.OptionalFieldAttribute()]
        private int EffDteField;
    
        [global::System.ComponentModel.BrowsableAttribute(false)]
        public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
            get {
                return this.extensionDataField;
            }
            set {
                this.extensionDataField = value;
            }
        }
    
        [System.Runtime.Serialization.DataMemberAttribute()]
        public int EffDte {
            get {
                return this.EffDteField;
            }
            set {
                if ((this.EffDteField.Equals(value) != true)) {
                    this.EffDteField = value;
                    this.RaisePropertyChanged("EffDte");
                }
            }
        }
    }
    

    关于如何保留对gethashcode的要求,但删除对客户机上任何代码的要求(作为更新或部分类)有什么想法吗?

    2 回复  |  直到 15 年前
        1
  •  3
  •   James Dunne    15 年前

    如果您真的需要您的WCF服务的所有C消费者在TACT中使用具有原始代码的相同模型,那么使用“添加服务引用”工具的“在引用的程序集中重用类型”功能。确保将您的模型/契约/接口分解成一个单独的程序集,其中没有作为共享“定义”程序集的其他实现代码。将此程序集标记为在“添加服务引用”工具生成客户端代理代码时重用类型的程序集。

    另外,只是一个主动的警告:只为您的服务提供一个“官方”的C服务客户端实现,从而简化您自己的工作。不要将Visual Studio生成的冗余服务引用代理添加到每个需要与服务连接的项目中。

    编辑:

    从最近的个人经验来看,我设计了一个模块化的、支持服务的API,允许我就模块化这一主题提供更一般的建议,因为它不仅与WCF服务有关,而且与总体设计有关。

    在我们的系统中,我们已经按照我上面的建议创建了一个只包含标记为 [DataContract] :域对象、模型、数据协定,无论您将它们称为什么。

    在此程序集中,还包含一组知识库接口,这些接口仅根据这些域对象定义方法。此程序集中还定义了强类型标识符结构,用于保存每个模型的标识值,因为这些模型是数据库持久化的,并且每个模型都有一个标识列。使用包装的结构 int 以这种方式比使用 int 从现在开始,我们得到了编译器辅助的语义分析,即 Model1ID Model2ID

        2
  •  0
  •   Ray Henry    15 年前

    namespace DCS2000.IDCardExclude.UI.IdCardManagerServiceReference
    {
      [Serializable]
      [DataContract]
      public partial class IdCard : DomainObject
      {
        public override int GetHashCode()
        {
            return EffDte.GetHashCode();
        }
      }
    }