我们正在执行所有域对象来实现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的要求的任何想法,但请删除客户端上任何代码的要求(作为更新或部分类)?

有帮助吗?

解决方案

如果您确实要求WCF服务的所有C#消费者都使用具有原始代码的相同型号,请使用“添加服务参考”工具的“参考汇编中的重用类型”功能。请确保将您的模型 /合同 /接口将其分解为单个组件,而其中没有其他实现代码,可以用作共享的“定义”程序集。将此汇编标记为从“添加服务参考”工具生成客户端代理代码时重复使用类型的一个。

另外,只是一个主动的警告:通过仅拥有一个“官方” C#服务客户端实施来简化自己的工作。不要将Visual Studio生成的冗余服务参考代理添加到需要与您服务连接的每个项目中。

编辑:

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

在我们的系统中,我们在创建单个“定义”组件时做了我上面建议的,该组件仅包含标记为 [DataContract]: :域对象,模型,数据合同,无论您想将其称为什么。

在此组件中,也是存储库接口的集合,它仅根据这些域对象定义方法。该组件中还定义了强大的标识符结构,用于每个模型的身份值,因为这些模型是数据库持续存在的,并且每个模型都有一个身份列。使用包裹的结构 intS以这种方式比使用更可取 int 自从现在以来,我们就获得了编译器辅助语义分析,即 Model1ID 不转换为 Model2ID 尽管他们在语义上代表两个不同的域,尽管两个域都可以由 int 类型。

驱动模块化的是这些存储库接口的定义。 WCF服务实现类简单地实现了所有必需的接口,与WCF服务客户端实现类,数据库存储库实现类,“缓存代理实现类”,“方法调用记录实现类”等类似。其他组件,即包含接口和模型的“定义”程序集中。这些类实现接口,并以相同的形式显示在消费者代码中。

关键是要保持特定实现类的API消费者代码不可知,仅引用界面。这些模型本身作为简单的数据容器保存,没有在其中找到业务逻辑实现。我相信这种模式被称为贫血,但是对我来说,“贫血”具有负面的含义,因此我不喜欢在描述该设计时使用该术语。

您获得的是实施业务逻辑的消费者代码,该逻辑不在乎它是与WCF服务或直接与数据库交谈,或者是无缝实现的缓存,还是正在记录您的方法调用或其他代理使用的内容你可以想出。

总而言之,设计界面并使您的生活更轻松。但是,只有在您对练习自我遏制的能力充满信心的情况下才这样做。在我设计的系统中,我们有T4模板,它们几乎生成WCF服务随附的所有样板代码,以至于我们必须手动执行的所有操作就是定义模型,设计界面并编写数据库访问代码。 WCF立面免费单击T4模板上的简单右键和“运行自定义工具”。我喜欢它。 :)

其他提示

修复部分类别的名称空间。您可能需要调整属性和继承。

namespace DCS2000.IDCardExclude.UI.IdCardManagerServiceReference
{
  [Serializable]
  [DataContract]
  public partial class IdCard : DomainObject
  {
    public override int GetHashCode()
    {
        return EffDte.GetHashCode();
    }
  }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top