نقطة انطلاق للهندسة المعمارية النظيفة مع ASP.NET CORE. تعتبر الهندسة المعمارية النظيفة هي الأحدث في سلسلة من الأسماء لنفس الهندسة المعمارية المربوطة بالاعتماد. ستجدها أيضًا تسميت سداسيًا أو موانئًا أو معمارية أو بنية البصل.
تعرف على المزيد حول الهندسة المعمارية النظيفة وهذا القالب في دورة NimblePros التي تقدم دورة الهندسة المعمارية النظيفة. استخدم رمز Ardalis لتوفير 20 ٪.
يتم استخدام هذه الهندسة المعمارية في مسار DDD الأساسي من قبل ستيف سميث وجولي ليرمان.
؟ اتصل بـ Steve's Company ، NimblePros ، للهندسة المعمارية النظيفة أو تدريب DDD و/أو مساعدة التنفيذ لفريقك.
تعرف على كيفية تنفيذ الهندسة المعمارية النظيفة من مدربي NimblePros سارة "Sadukie" Dutkiewicz و Steve "Ardalis" Smith.
إذا كنت ترغب في ذلك أو كنت تستخدم هذا المشروع لتعلم أو بدء الحل ، فيرجى إعطائه نجمة. شكرًا!
أو إذا كنت تشعر بالسخاء حقًا ، فنحن ندعم الآن رعاية GitHub - انظر الزر أعلاه.
أرجو أن أعلن أن صندوق Amazon AWS's Foss قد اختار منح رعاية مدتها 12 شهرًا لهذا المشروع. شكرا لك ، وبفضل جميع رعاة ماضي والحاليين الآخرين!
بشكل افتراضي ، يستخدم الموقع HTTPS ويتوقع منك الحصول على شهادة مطور موقعة ذاتيًا لاستخدام مضيف محلي. إذا حصلت على خطأ مع Chrome ، فراجع هذه الإجابة لتعليمات التخفيف.
الفرع الرئيسي يستخدم الآن .NET 9 . هذا يتوافق مع إصدار حزمة Nuget 10.x. الإصدارات السابقة متوفرة - انظر إصداراتنا.
لاستخدام هذا القالب ، هناك بعض الخيارات:
dotnet new (موصى به)أولاً ، قم بتثبيت القالب من Nuget (https://www.nuget.org/packages/ardalis.cleanchitecture.template/):
dotnet new install Ardalis.CleanArchitecture.Template يمكنك رؤية الخيارات المتاحة عن طريق تشغيل الأمر مع -? خيار:
dotnet new clean - arch - ?
ASP.NET Clean Architecture Solution (C # )
Author: Steve Smith @ardalis , Erik Dahl
Usage:
dotnet new clean - arch [ options ] [ template options ]
Options:
- n , -- name < name > The name for the output being created. If no name is specified , the name of the output
directory is used.
- o , -- output < output > Location to place the generated output.
-- dry - run Displays a summary of what would happen if the given command line were run if it would result
in a template creation.
-- force Forces content to be generated even if it would change existing files.
-- no - update-check Disables checking for the template package updates when instantiating a template.
-- project < project > The project that should be used for context evaluation.
- lang , -- language < C # > Specifies the template language to instantiate.
-- type < project > Specifies the template type to instantiate.
Template options:
-as , -- aspire Include .NET Aspire.
Type: bool
Default : false يجب أن ترى القالب في قائمة القوالب من dotnet new list بعد هذا التثبيت بنجاح. ابحث عن "ASP.NET Clean Architecture Solution" مع الاسم القصير لـ "Clean-Arch".
انتقل إلى الدليل الأصل الذي ترغب في إنشاء مجلد الحل.
قم بتشغيل هذا الأمر لإنشاء بنية الحل في اسم المجلد الفرعي Your.ProjectName :
dotnet new clean-arch -o Your.ProjectName
سيتم إنشاء دليل وملف الحلول Your.ProjectName .
مثال: 
شكرًا @dahlsailrunner لمساعدتكم في الحصول على هذا العمل!
القضايا المعروفة :
اعتبارًا من الإصدار 9 ، لا يتضمن قالب الحل هذا سوى دعم نقاط نهاية API باستخدام مكتبة FastEndPoints. إذا كنت ترغب في استخدام مكتبة ApiendPoints الخاصة بي ، وصفحات الحلاقة ، و/أو وحدات التحكم ، يمكنك استخدام القالب الأخير الذي تضمنها ، الإصدار 7.1. بالتناوب ، تمت إضافتها بسهولة إلى هذا القالب بعد التثبيت.
لاستخدام Ardalis.ApiendPoints بدلاً من (أو بالإضافة إلى) FastEndPoints ، ما عليك سوى إضافة المرجع واستخدم الفئات الأساسية من الوثائق.
dotnet add package Ardalis.ApiEndpointsستحتاج إلى إضافة دعم لوحدات التحكم إلى ملف البرنامج. تحتاج:
builder . Services . AddControllers ( ) ; // ControllersWithView if you need Views
// and
app . MapControllers ( ) ;بمجرد وضعها في مكانها ، يجب أن تكون قادرًا على إنشاء مجلد وحدات تحكم و (اختياريًا) مجلد طرق عرض ويجب أن يعمل كل شيء كما هو متوقع. أنا شخصياً أجد أن صفحات الحلاقة أفضل بكثير من وحدات التحكم ووجهات النظر ، لذا إذا لم تكن قد قمت بالتحقيق بالكامل في صفحات الحلاقة ، فقد ترغب في القيام بذلك الآن قبل اختيار المشاهدات.
ستحتاج إلى إضافة دعم لصفحات الحلاقة إلى ملف البرنامج. تحتاج:
builder . Services . AddRazorPages ( ) ;
// and
app . MapRazorPages ( ) ;ثم يمكنك فقط إضافة مجلد صفحات في جذر المشروع والانتقال من هناك.
للبدء بناءً على هذا المستودع ، تحتاج إلى الحصول على نسخة محليًا. لديك ثلاثة خيارات: شوكة أو استنساخ أو تنزيل. معظم الوقت ، ربما تريد فقط التنزيل.
يجب عليك تنزيل المستودع ، وإلغاء حظر ملف zip ، واستخراجه إلى مجلد جديد إذا كنت ترغب فقط في اللعب مع المشروع أو كنت ترغب في استخدامه كنقطة انطلاق للتطبيق.
يجب أن تتفوق على هذا المستودع فقط إذا كنت تخطط لتقديم طلب سحب. أو إذا كنت ترغب في الاحتفاظ بنسخة من لقطة من المستودع في حساب GitHub الخاص بك.
يجب عليك استنساخ هذا المستودع إذا كنت أحد المساهمين وتواجهه الوصول إليه. وإلا فأنت تريد أحد الخيارات الأخرى.
يجب ألا تحتاج إلى القيام بذلك لاستخدام هذا القالب ، ولكن إذا كنت تريد إعداد الترحيل بشكل صحيح في مشروع البنية التحتية ، فأنت بحاجة إلى تحديد اسم المشروع عند تشغيل أمر الترحيل.
في Visual Studio ، افتح وحدة تحكم Package Manager ، وقم بتشغيل Add-Migration InitialMigrationName -StartupProject Your.ProjectName.Web -Context AppDbContext -Project Your.ProjectName.Infrastructure .
في محطة مع CLI ، يكون الأمر مشابهًا. قم بتشغيل هذا من دليل مشروع الويب:
dotnet ef migrations add MIGRATIONNAME - c AppDbContext - p .. / Your.ProjectName.Infrastructure / Your.ProjectName.Infrastructure.csproj - s Your.ProjectName.Web.csproj - o Data / Migrations لاستخدام sqlserver ، تغيير options.UseSqlite(connectionString)); إلى options.UseSqlServer(connectionString)); في ملفك Your.ProjectName.Infrastructure.StartupSetup . تذكر أيضًا استبدال SqliteConnection مع DefaultConnection في ملفك Your.ProjectName.Web.Program .
لتحديث قاعدة البيانات ، استخدم هذا الأمر من مجلد مشروع الويب (استبدل Clean.Architecture باسم مشروعك):
dotnet ef database update - c AppDbContext - p .. / Clean .Architecture.Infrastructure / Clean .Architecture.Infrastructure.csproj - s Clean .Architecture.Web.csprojالهدف من هذا المستودع هو توفير بنية حل أساسية يمكن استخدامها لإنشاء تطبيقات التصميم القائمة على المجال (DDD) أو ببساطة تطبيقات صلبة بشكل جيد باستخدام .NET Core. تعرف على المزيد حول هذه الموضوعات هنا:
إذا كنت معتادًا على بناء التطبيقات كمشروع واحد أو كمجموعة من المشاريع التي تتبع واجهة المستخدم التقليدية -> طبقة العمل -> طبقة الوصول إلى البيانات "N -tier" ، أوصيك بالتحقق من هاتين الدورتين (من الناحية المثالية قبل أساسيات DDD):
يحتفظ ستيف سميث أيضًا بتطبيق Microsoft المرجعي ، Eshoponweb ، والكتاب الإلكتروني المجاني المرتبط به. تحقق منها هنا:
لاحظ أن الهدف من هذا المشروع والمستودع ليس تقديم عينة أو تطبيق مرجعي. من المفترض أن يكون مجرد قالب ، ولكن مع وجود قطع كافية لتظهر لك أين تنتمي الأشياء أثناء إعداد الحل الفعلي. بدلاً من "class1.cs" عديمة الفائدة ، هناك بعض الفصول الحقيقية. احذفها بمجرد أن تفهم سبب وجودها ومكان وضع ملفاتك المماثلة الخاصة بك. يوجد تطبيق عينة في مجلد /sample ، إذا كنت تبحث عن ذلك.
لقد استخدمت مجموعة المبتدئين هذه لتدريس أساسيات ASP.NET Core باستخدام مفاهيم وأنماط التصميم التي تعتمد على المجال لبعض الوقت الآن (تبدأ عندما كان ASP.NET Core لا يزال في ما قبل الإصدار). عادةً ما أقوم بتدريس ورشة عمل عملية لمدة يوم أو يومين قبل أحداث مثل Devintersection ، أو ورش عمل خاصة في الموقع للشركات التي تتطلع إلى رفع مستوى فرقها مع أحدث تقنيات التطوير والتقنيات. لا تتردد في الاتصال بي إذا كنت ترغب في معلومات حول ورش العمل القادمة.
الهدف من قالب الحل هذا هو توفير مجموعة بداية إلى حد ما للمشاريع الجديدة. لا يتضمن كل إطار أو أداة أو ميزة ممكنة قد يستفيد منها تطبيق Enterprise معين. تتأرجح خيارات التكنولوجيا الخاصة بأشياء مثل الوصول إلى البيانات في التكنولوجيا الأكثر شيوعًا والتي يمكن الوصول إليها لمعظم مطوري برامج الأعمال باستخدام مكدس تقنية Microsoft. لا يتضمن (حاليًا) دعمًا مكثفًا لأشياء مثل التسجيل أو المراقبة أو التحليلات ، على الرغم من أنه يمكن إضافتها بسهولة. فيما يلي قائمة بالتبعيات التكنولوجية التي تتضمنها ، ولماذا تم اختيارها. يمكن بسهولة تبديل معظمها لتكنولوجياك المفضلة ، لأن طبيعة هذه البنية هي دعم النموذج والتغليف.
يعد التحقق من صحة إدخال المستخدم شرطًا لجميع تطبيقات البرامج. والسؤال هو ، أين من المنطقي تنفيذها بطريقة موجزة وأنيقة؟ يتضمن قالب الحل هذا 4 مشاريع منفصلة ، قد يكون كل منها مسؤولاً عن أداء التحقق من الصحة وكذلك فرض ثبات الأعمال (والذي ، نظرًا لوجود التحقق من الصحة بالفعل ، يتم تصميمه عادةً كاستثناءات).
يجب أن يعتمد نموذج المجال نفسه بشكل عام على التصميم الموجهة للكائنات لضمان أن يكون دائمًا في حالة متسقة. إنه يعزز التغليف ويقصر الوصول إلى طفرة الدولة العامة لتحقيق ذلك ، ويفترض أن أي وسيطات تم تمريرها بالفعل قد تم التحقق من صحتها ، لذلك خالية من القيم غير السليمة التي تعطي استثناءات ، وليس نتائج التحقق من الصحة ، في معظم الحالات.
يتضمن مشروع الاستخدام / التطبيق مجموعة من جميع الأوامر والاستعلامات التي يدعمها النظام. غالبًا ما تكون مسؤولة عن التحقق من صحة كائنات الأمر والاستعلام. يتم القيام بذلك بسهولة باستخدام سلسلة من نمط المسؤولية عبر سلوكيات MediaTr أو بعض خطوط الأنابيب الأخرى.
يتضمن مشروع الويب جميع نقاط نهاية API ، والتي تتضمن أنواع طلبها وأنواع الاستجابة الخاصة بها ، بعد نمط Repr. تتضمن مكتبة FastEndPoints دعمًا مدمجًا للتحقق من الصحة باستخدام FluentValidation على أنواع الطلبات. هذا هو مكان طبيعي لإجراء التحقق من صحة المدخلات كذلك.
يمكن اعتبار وجود التحقق من الصحة في كل من نقاط نهاية API ثم مرة أخرى على مستوى حالة الاستخدام زائدة عن الحاجة. هناك مفاضلات لإضافة نفس التحقق من الصحة في مكانين ، واحد لطلبات API وآخر للرسائل المرسلة لاستخدام معالجات الحالات. بعد الترميز الدفاعي ، غالبًا ما يكون من المنطقي إضافة التحقق من الصحة في كلا المكانين ، حيث أن النفقات العامة ضئيلة وغالبًا ما تستحق راحة البال في ذهنها ، وغالبًا ما يستحق ذلك.
المشروع الأساسي هو مركز تصميم الهندسة المعمارية النظيفة ، ويجب أن تشير جميع تبعيات المشروع الأخرى نحوه. على هذا النحو ، لديها عدد قليل جدا من التبعيات الخارجية. يجب أن يتضمن المشروع الأساسي نموذج المجال بما في ذلك أشياء مثل:
يمكنك معرفة المزيد حول هذه الأنماط وكيفية تطبيقها هنا:
مشروع اختياري ، لقد قمت بتضمينه لأن العديد من الأشخاص كانوا يطالبون به ويسهل إزالته بدلاً من إضافته لاحقًا. ويشار إلى هذا أيضًا باسم طبقة خدمات التطبيق أو تطبيقات التطبيق. يتم تنظيم مشروع حالات الاستخدام بعد CQRs في الأوامر والاستعلامات (فكرت في وجود مجلدات Commands Queries ولكن شعرت أنها تضاف القليل - المجلدات لكل أمر أو استعلام فعلي كافي دون تعشيش إضافي). تحلق الأوامر نموذج المجال وبالتالي يجب أن تستخدم دائمًا تجريد المستودع للوصول إلى البيانات (المستودعات هي كيف يجلب المرء أنواع نماذج النطاق). يتم قراءة الاستعلامات ، وبالتالي لا تحتاج إلى استخدام نمط المستودع ، ولكن بدلاً من ذلك يمكن استخدام أي خدمة أو نهج استعلام أكثر ملاءمة.
نظرًا لأن مشروع حالات الاستخدام يتم إعداده ليعتمد على Core ولا يعتمد على البنية التحتية ، فلا يزال هناك حاجة إلى تجريدات محددة للوصول إلى البيانات. ويمكنه استخدام أشياء مثل المواصفات ، والتي يمكن أن تساعد في بعض الأحيان في تغليف منطق الاستعلام بالإضافة إلى تعيين نوع النتيجة. لكن ليس من الضروري استخدام المستودع/المواصفات - يمكنه فقط إصدار استعلام SQL أو استدعاء إجراء مخزن إذا كانت هذه هي الطريقة الأكثر فعالية للحصول على البيانات.
على الرغم من أن هذا مشروع اختياري يجب تضمينه (بدونه ، فإن نقاط نهاية واجهة برمجة التطبيقات الخاصة بك ستعمل مباشرة مع نموذج النطاق أو خدمات الاستعلام) ، إلا أنه يوفر مكانًا لطيفًا لاستخدام واجهة المستخدم لإضافة اختبارات آلية ، ويقرض نفسه على تطبيق السياسات لتطبيق المخاوف المتقاطعة ، وما إلى ذلك). يتضمن القالب مثالاً على ذلك للتسجيل ، والذي يقع في حزمة SerquerKernel nuget.
يجب تنفيذ معظم تبعيات طلبك على الموارد الخارجية في الفصول المحددة في مشروع البنية التحتية. يجب أن تنفذ هذه الفئات واجهات محددة في القلب. إذا كان لديك مشروع كبير للغاية مع العديد من التبعيات ، فقد يكون من المنطقي أن يكون لديك مشاريع بنية تحتية متعددة (على سبيل المثال البنية التحتية. يتضمن القالب تطبيقات الوصول إلى البيانات وتطبيقات الأحداث ، ولكنك ستقوم أيضًا بإضافة أشياء مثل مقدمي البريد الإلكتروني ، وصول الملفات ، وعملاء واجهة برمجة تطبيقات الويب ، وما إلى ذلك ، حتى لا تضيف اقتران إلى مشاريعك الأساسية أو واجهة المستخدم.
نقطة إدخال التطبيق هي مشروع الويب ASP.NET Core (أو ربما مشروع Aspirehost ، والذي بدوره يقوم بتحميل مشروع الويب). هذا في الواقع تطبيق وحدة تحكم ، مع طريقة public static void Main في Program.cs . إنه يعزز FastEndPoints ونمط Repr لتنظيم نقاط نهاية واجهة برمجة التطبيقات الخاصة به.
يتم استخدام نواة مشتركة لتبادل العناصر المشتركة بين السياقات المحدودة. إنه مصطلح DDD ، لكن العديد من المؤسسات تستفيد من المشاريع أو الحزم "الشائعة" للأشياء المفيدة للمشاركة بين العديد من التطبيقات.
أوصي بإنشاء مشروع وحل مشترك منفصل إذا كنت ستحتاج إلى مشاركة رمز بين سياقات متعددة محدودة (انظر أساسيات DDD). أوصي كذلك بأن يتم نشر هذا كحزمة Nuget (على الأرجح على الأرجح داخل مؤسستك) ويشار إليها على أنها تبعية من Nuget من قبل تلك المشاريع التي تتطلب ذلك.
سابقا تم تضمين مشروع لـ ServentKernel في هذا المشروع. ومع ذلك ، للأسباب المذكورة أعلاه ، جعلتها حزمة منفصلة ، Ardalis.sharedkernel ، والتي يجب أن تستبدلها بنفسك عند استخدام هذا القالب .
إذا كنت ترغب في رؤية مثال آخر على حزمة SerquerKernel ، فإن تلك التي أستخدمها في دورة DDD المحدثة الخاصة بي على Nuget هنا.
يمكن تنظيم مشاريع الاختبار استنادًا إلى نوع الاختبار (الوحدة ، الوظيفية ، التكامل ، الأداء ، إلخ) أو عن طريق المشروع الذي يختبرونه (Core أو البنية التحتية أو الويب) أو كليهما. بالنسبة لهذه المجموعة المبتدئة البسيطة ، يتم تنظيم مشاريع الاختبار بناءً على نوع الاختبار ، مع مشاريع الاختبار الوظيفية والوظيفية والتكامل الموجودة في هذا الحل. الاختبارات الوظيفية هي نوع خاص من اختبار التكامل الذي يؤدي الاختبار تحت الجلد لواجهة برمجة التطبيقات لمشروع الويب ، دون استضافة موقع ويب حقيقي أو الذهاب عبر الشبكة بالفعل. لقد قمت بإنشاء مجموعة من مساعدي الاختبار لجعل هذه الأنواع من الاختبارات أقصر وأسهل في الحفاظ عليها.
يحتوي قالب الحل هذا على رمز مدمج لدعم بعض الأنماط الشائعة ، وخاصة أنماط التصميم التي تعتمد على المجال. فيما يلي نظرة عامة موجزة على كيفية عمل عدد قليل منهم.
تعد أحداث المجال نمطًا رائعًا لفصل تشغيل التشغيل لعملية من تنفيذها. هذا مفيد بشكل خاص من داخل كيانات المجال لأن معالجات الأحداث يمكن أن يكون لها تبعيات بينما الكيانات نفسها عادة لا تفعل ذلك. في العينة ، يمكنك رؤية هذا في العمل باستخدام طريقة ToDoItem.MarkComplete() . يوضح مخطط التسلسل التالي كيف يتم استخدام الحدث ومعالجه عند تمييز عنصر ما من خلال نقطة نهاية واجهة برمجة تطبيقات الويب.
