سؤال

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

الآن أنا أعمل في مشروع حيث تحتوي بعض كائنات الوصول من البيانات الخاصة بي على طرق مثل حفظ () إلخ والتي تحتاج إلى الوصول إلى مشروع البيانات. لذلك، سيكون لدي مرجع دائري إذا حاولت استخدام النموذج / المشروع المشترك في مشروع البيانات.

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

هل كانت مفيدة؟

المحلول

هذا هو ما لدي في مشروعي.

1.) Application.infrasicure.

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

2.) Application.datamodel.

  • بيانات مكتوبة لقاعدة البيانات.
  • امتدت الطوابق الطوابق لتضمين المعاملات والميزات الأخرى التي قد أحتاج إليها.

3.) application.dataaccess.

  • فصول الوصول إلى البيانات.
  • المكان الفعلي حيث يتم الاستعلام عن إجراءات قاعدة البيانات باستخدام مجموعة البيانات المكتوبة الأساسية.

4.) application.domainoBjects.

  • كائنات الأعمال ومجموعات كائن الأعمال.
  • عودة.

5.) Application.BusinessLayer.

  • يوفر فئات المدير التي يمكن الوصول إليها من طبقة العرض التقديمي.
  • httphandlers.
  • صف صفحتي الخاصة.
  • المزيد من الأشياء تذهب هنا ..

6.) تطبيق.WebClient. أو application.windowsclient.

  • طبقة العرض التقديمي
  • يأخذ المراجع من Application.BusinessLayer و Application.BusinessObjects.

يتم استخدام Application.BusinessObjects عبر التطبيق ويسافر عبر جميع الطبقات كلما تطالب [باستثناء Application.datamodel و Application.infrasulture

يتم تعريف جميع استفساراتي فقط Application.datamodel.

application.dataaccess إرجاع أو يأخذ كائنات العمل كجزء من أي عملية وصول إلى البيانات. يتم إنشاء كائنات الأعمال بمساعدة سمات الانعكاس. يتم تمييز كل كائن أعمال مع تعيين سمة إلى الجدول المستهدف في قاعدة البيانات والخصائص داخل كائن العمل مع تعيين سمات لاستهداف Coloumn في جدول بيانات البيانات المعني.

يتيح لي إطار التحقق من صحة كل حقل بمساعدة التحقق من الصرف المعين.

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

سيبدو كائن أعمال عينة مثل هذا في طلبي.

user.cs.

[TableMapping("Users")]
public class User : EntityBase
{
    #region Constructor(s)
    public AppUser()
    {
        BookCollection = new BookCollection();
    }
    #endregion

    #region Properties

    #region Default Properties - Direct Field Mapping using DataFieldMappingAttribute

    private System.Int32 _UserId;

    private System.String _FirstName;
    private System.String _LastName;
    private System.String _UserName;
    private System.Boolean _IsActive;

    [DataFieldMapping("UserID")]
    [DataObjectFieldAttribute(true, true, false)]
    [NotNullOrEmpty(Message = "UserID From Users Table Is Required.")]
    public override int Id
    {
        get
        {
            return _UserId;
        }
        set
        {
            _UserId = value;
        }
    }

    [DataFieldMapping("UserName")]
    [Searchable]
    [NotNullOrEmpty(Message = "Username Is Required.")]
    public string UserName
    {
        get
        {
            return _UserName;
        }
        set
        {
            _UserName = value;
        }
    }

    [DataFieldMapping("FirstName")]
    [Searchable]
    public string FirstName
    {
        get
        {
            return _FirstName;
        }
        set
        {
            _FirstName = value;
        }
    }

    [DataFieldMapping("LastName")]
    [Searchable]
    public string LastName
    {
        get
        {
            return _LastName;
        }
        set
        {
            _LastName = value;
        }
    }

    [DataFieldMapping("IsActive")]
    public bool IsActive
    {
        get
        {
            return _IsActive;
        }
        set
        {
            _IsActive = value;
        }
    }

    #region One-To-Many Mappings
    public BookCollection Books { get; set; }

    #endregion

    #region Derived Properties
    public string FullName { get { return this.FirstName + " " + this.LastName; } }

    #endregion

    #endregion

    public override bool Validate()
    {
        bool baseValid = base.Validate();
        bool localValid = Books.Validate();
        return baseValid && localValid;
    }
}

bookcollection.cs.

/// <summary>
/// The BookCollection class is designed to work with lists of instances of Book.
/// </summary>
public class BookCollection : EntityCollectionBase<Book>
{
    /// <summary>
    /// Initializes a new instance of the BookCollection class.
    /// </summary>
    public BookCollection()
    {
    }

    /// <summary>
    /// Initializes a new instance of the BookCollection class.
    /// </summary>
    public BookCollection (IList<Book> initialList)
        : base(initialList)
    {
    }
}

نصائح أخرى

لا أعتقد أن لديك N-Tier الخاص بك على حق تماما. يبدو وكأنه تقوم ببناء المزيد من أنظمة ثنائية المستوى.

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

N-Tier يأتي عندما يكون لديك أكثر من 3 "Tiers"، ولكن نفس المبدأ: كل طبقة تعرف فقط كيفية الاستخدام (ولا تحتاج فقط إلى مرجع إلى) واحد أدناه، ثم يوفر واجهة برمجة تطبيقات للطبقة أعلاه هو - هي. في مشاريعي الخاصة، أتناول العرض التقديمي الخاص بك والشركات التجارية والبيانات الخاصة بك وتوفير المستوى الرابع "الترجمة" بين الأعمال والبيانات. وبهذه الطريقة، يمكن أن تعيد الطبقة البيانات أنواعا عامة مثل DataSet و DataTable و Datarow و Tier Tier فقط يجب أن تعمل من حيث الكائنات التجارية المكتوبة بقوة. الطبقة الترجمة فقط يحول بين كائنات البيانات العامة وكائنات مكتوبة بشدة. وبهذه الطريقة، من المرجح أن يتطلب التغيير في إحدى الصفائح التقليدية تغييرا في آخر.

يجب أن تخزن طبقة البيانات المعلومات من حيث الصفوف والأعمدة (ربما استخدام مجموعات البيانات المكتوبة، إذا كنت ترغب في ذلك)، إذا كنت تستخدم العلاقة الصحية. لا "كائنات عمل".

يجب أن تستخدم طبقة العمل "كائنات العمل" الخاصة بك. يمكن أن يكون هناك إشارة إلى مشروع BusinessObjects.

باختصار:

  • واجهة المستخدم لديها إشارات إلى الأعمال التجارية والأعمال
  • العمل لديه إشارات إلى BusinessObjects والبيانات

أتمنى أن يساعدك هذا.

لدي مشروع BusinessOpjects، جانب الخادم تخزين التعيينات (ORM) وخدمة DataAccess المقابلة تعرض عمليات CRUD عليها (وغيرها مثل Getall) إلخ.

أود أن أقترح إنشاء وواجهة لما تريده في المشروع النموذجي، وتنفيذ هذا التعريف في طبقة البيانات. بهذه الطريقة يمكن للمشروعات الثلاثة (أربعة؟) استخدام هذا التعريف، دون معرفة كيفية تنفيذها.

في رأيي، يجب أن يكون لدى طبقة العمل فقط معرفة كائنات الوصول إلى البيانات. يجب استخدامها لعمليات البيانات مع تطبيق قواعدها التجارية والمنطق الخاص بها، ثم إعادة الكائنات البكمية (مثل كائنات نقل البيانات) إلى طبقة UI أعلاه.

يمكنك استخدام شيء مثل Automapper. للخريطة تلقائيا بين البيانات والكائنات التجارية.

يعتمد حقا على النمط، إذا كنت تستخدم MVC (نمط وحدة تحكم أمامية)، فإن النموذج هو التمثيل الخاص بالمجال للبيانات التي يعمل عليها التطبيق (عموما مساعدة orm مع هذا) نستخدم مشروع بيانات لهذه الفصول وبعد

النماذج ليست كائنات وصول إلى البيانات، لذلك يصبح الوصول إلى البيانات في شكل مستودعات في مشروع مختلف. الخدمات لقواعد الأعمال وأخيرا مشروع الويب. في هذا النهج، يتم الرجوع إلى Data.dll في جميع المشاريع. النموذج يشبه omnipresent.

DATA(Domain Model) -> REPOSITORY(Data Access) -> SERVICE(Business Rules) -> WEB
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top