保持WCF抽象方法服务器端的方法
-
28-09-2019 - |
题
我们正在执行所有域对象来实现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]
: :域对象,模型,数据合同,无论您想将其称为什么。
在此组件中,也是存储库接口的集合,它仅根据这些域对象定义方法。该组件中还定义了强大的标识符结构,用于每个模型的身份值,因为这些模型是数据库持续存在的,并且每个模型都有一个身份列。使用包裹的结构 int
S以这种方式比使用更可取 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();
}
}
}