سؤال

نحن نفرض جميع كائنات المجال لدينا لتنفيذ 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 الخاصة بك نفس النماذج مع الكود الأصلي في براعة ، فاستخدم ميزة إعادة استخدام "Add Service Reference" في التجميعات المرجعية ". تأكد من تقسيم النماذج / العقود / الواجهات الخاصة بك إلى مجموعة واحدة مع عدم وجود رمز تنفيذ آخر فيه يعمل كتجميع "تعريف" مشترك. حدد هذا التجميع باعتباره واحد لإعادة استخدام الأنواع من عندما تقوم أداة "إضافة مرجع الخدمة" بإنشاء رمز وكيل العميل الخاص بك.

أيضًا ، مجرد تحذير استباقي: تبسيط الأشياء بنفسك من خلال تطبيق عميل خدمة C# "رسمي" واحد فقط لخدمتك. لا تضيف الوكلاء المرجعيين للخدمة المتكررة التي تم إنشاؤها بواسطة Visual Studio إلى كل مشروع يتطلب الاتصال مع خدمتك.

تعديل:

في حديثه من التجربة الشخصية الحديثة ، بعد أن صمم واجهة برمجة تطبيقات معيارية تدعم الخدمة ، اسمح لي بتقديم المزيد من المشورة العامة حول موضوع الوحدات النمطية لأنها تتعلق ليس فقط بخدمات WCF ، ولكن التصميم الشامل.

في نظامنا ، فعلنا ما اقترحته أعلاه في إنشاء مجموعة "تعريف" واحد يحتوي على كائنات فقط محددة [DataContract]: كائنات المجال ، النماذج ، عقود البيانات ، كل ما تحب الإشارة إليها.

في هذه المجموعة هي أيضًا مجموعة من واجهات المستودعات التي تحدد الأساليب فقط من حيث كائنات المجال هذه. هناك أيضًا هياكل معرفات من النوع المحددة في هذه التجميع والتي يتم استخدامها للاحتفاظ بقيم الهوية لكل نموذج لأن هذه النماذج مستمرة قاعدة بيانات ويحتوي كل منها على عمود هوية. باستخدام الهياكل التي تلتف intS بهذه الطريقة هو الأفضل استخدام int نفسها منذ الآن نحصل على التحليل الدلالي بمساعدة البرمجيات ، أي Model1ID غير قابل للتحويل إلى Model2ID لأنها تمثل دلالة مجالين مختلفين على الرغم من حقيقة أن كلا المجالين يمثلان من قبل int يكتب.

ما يدفع النموذج هو تعريف واجهات المستودع هذه. تقوم فئة تنفيذ خدمة WCF ببساطة بتنفيذ جميع الواجهات المطلوبة ، على غرار فئة تنفيذ عميل خدمة WCF ، وفئة تنفيذ مستودع قاعدة البيانات ، وفئة تنفيذ وكيل التخزين المؤقت ، وفئة تطبيق التسجيل للاستدعاء ، وما إلى ذلك. التجميعات الأخرى ، أي ليس في مجموعة "التعريف" التي تحتوي على الواجهات والنماذج. تنفذ هذه الفئات الواجهات وتظهر لرمز المستهلك كما هو متماثل.

المفتاح هو الحفاظ على رمز المستهلك API الخاص بك لدرس فئات التنفيذ المحددة والرجوع فقط إلى الواجهات. يتم الاحتفاظ بالنماذج نفسها كحاويات بيانات بسيطة بدون تطبيق منطق تجاري موجود داخلها. أعتقد أن هذا النمط يشار إليه باسم فقر الدم ، لكن بالنسبة لي "فقر الدم" له دلالات سلبية ، لذلك لا أحب استخدام هذا المصطلح عند وصف هذا التصميم.

ما تحصل عليه هو تنفيذ رمز المستهلك الذي لا يهتم بما إذا كان يتحدث إلى خدمة WCF أو مباشرة إلى قاعدة بيانات ، أو أنه يتم تنفيذ التخزين المؤقت بسلاسة ، أو أن دعوات الطريقة التي يتم تسجيلها ، أو أيا كان ما يستخدمه الوكيل الآخر يمكنك الخروج.

باختصار ، التصميم مع واجهات وجعل حياتك أسهل لنفسك. ولكن فقط افعل هذا إذا كنت واثقا من قدرتك على ممارسة ضبط النفس. في نظامنا الذي صممته ، لدينا قوالب T4 التي تولد جميع رمز Boilerplate تقريبًا الذي يأتي جنبا إلى جنب مع خدمات 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