مستودع أحادي مع C#: تنظيم الكود عمليًا
المستودع الأحادي (monorepo) هو نهج لإدارة الكود المصدري، حيث يتم تخزين جميع مشاريع الشركة أو الفريق في مستودع واحد. في عالم C# و .NET، أصبح هذا النهج شائعًا بشكل متزايد بفضل تبسيط التطوير المشترك، وتوحيد إصدارات التبعيات، و CI/CD المركزي. ومع ذلك، بدون تنظيم صحيح للكود، يمكن أن يتحول المستودع الأحادي إلى فوضى. في هذه المقالة، سنستعرض التقنيات العملية لتنظيم كود C# في مستودع أحادي: من هيكل المجلدات إلى إعداد البناء.
1. هيكل المجلدات: أساس النظام
الخطوة الأولى نحو مستودع أحادي ناجح هي التسلسل الهرمي المدروس للدلائل. يُوصى باتباع اتفاقية حيث يقع كل مشروع في مجلد منفصل، ويتم وضع المكونات المشتركة في src/shared. مثال على الهيكل الأساسي:
/monorepo├── src/│ ├── shared/│ │ ├── CommonLib/ # أدوات مساعدة عامة، DTO، واجهات│ │ └── LoggingLib/ # تسجيل│ ├── services/│ │ ├── AuthService/ # خدمة مصغرة للمصادقة│ │ └── OrderService/ # خدمة مصغرة للطلبات│ └── apps/│ ├── WebApi/ # تطبيق الويب الرئيسي│ └── ConsoleApp/ # أداة وحدة التحكم├── tests/│ ├── unit/│ │ ├── CommonLib.Tests/│ │ └── AuthService.Tests/│ └── integration/│ └── IntegrationTests/├── docs/├── scripts/├── .gitignore├── Directory.Build.props└── global.jsonالنقاط الرئيسية:
- src/ — الكود المصدري لجميع المشاريع.
- shared/ — المكتبات المستخدمة من قبل عدة مشاريع.
- services/ — الخدمات المصغرة أو الوحدات.
- apps/ — التطبيقات النهائية (Web API، Console، Blazor).
- tests/ — الاختبارات، معزولة عن الكود المصدري.
مثل هذا الهيكل يسمح بالعثور بسهولة على الكود، وتجنب التبعيات الدائرية، وتبسيط إعداد CI/CD.
2. إدارة المشاريع باستخدام Directory.Build.props
في المستودع الأحادي، غالبًا ما تكون هناك حاجة لتعيين إعدادات مشتركة لجميع المشاريع: إصدارات .NET، الحزم المشتركة، قواعد تحليل الكود. بدلاً من التكرار في كل ملف .csproj، استخدم ملف Directory.Build.props في جذر المستودع. مثال:
<Project> <PropertyGroup> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> </PropertyGroup>
<ItemGroup> <PackageReference Include="SonarAnalyzer.CSharp" Version="9.*" /> </ItemGroup></Project>الآن، كل مشروع فرعي يرث تلقائيًا هذه الإعدادات. إذا كنت بحاجة إلى تجاوزها لمشروع معين، فقط أضف الخصائص في ملف .csproj الخاص به - فهي لها الأولوية.
بالإضافة إلى ذلك، يمكنك إنشاء Directory.Build.targets لأهداف البناء المشتركة (مثل نسخ الملفات بعد البناء).
3. إدارة التبعيات: نهج مركزي
إحدى المشاكل الرئيسية للمستودع الأحادي هي تضارب إصدارات الحزم. في .NET 8، ظهر دعم مدمج لـ إدارة الحزم المركزية (Central Package Management, CPM). للقيام بذلك، قم بإنشاء ملف Directory.Packages.props في الجذر:
<Project> <PropertyGroup> <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> </PropertyGroup> <ItemGroup> <PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" /> <PackageVersion Include="Serilog" Version="3.1.1" /&g