Tier 1: Technical Infrastructure (کاملاً قابل اشتراک) ⚙️
کدهای Plumbing که تمام Sliceها به یک اندازه از آن بهره میبرند:
• Logging adapters
• Database connection factories
• Auth middleware
•الگوی Result
•Validation pipelines
این موارد را در یک پروژهٔ Shared.Kernel یا Infrastructure قرار دهید.
همچنین میتوانند فقط یک فولدر باشند.
این بخشها بهندرت بهخاطر نیازهای کسبوکار تغییر میکنند.
نمونهٔ مناسب اشتراکگذاری: Technical Kernel
public readonly record struct Result
{
public bool IsSuccess { get; }
public string Error { get; }
private Result(bool isSuccess, string error)
{
IsSuccess = isSuccess;
Error = error;
}
public static Result Success() => new(true, string.Empty);
public static Result Failure(string error) => new(false, error);
}
Tier 2: Domain Concepts (اشتراکگذاری و انتقال منطق به پایینترین سطح) 🧩
این یکی از بهترین مکانها برای Shared کردن منطق است.
بهجای پخشکردن Business Ruleها در Sliceهای مختلف، منطق را در Entities و Value Objects قرار دهید.
نمونهٔ مناسب: Entity با منطق تجاری
public class Order
{
public Guid Id { get; private set; }
public OrderStatus Status { get; private set; }
public List<OrderLine> Lines { get; private set; }
public bool CanBeCancelled() => Status == OrderStatus.Pending;
public Result Cancel()
{
if (!CanBeCancelled())
{
return Result.Failure("Only pending orders can be cancelled.");
}
Status = OrderStatus.Cancelled;
return Result.Success();
}
}
حالا Sliceهای زیر همگی دقیقاً از همین قوانین استفاده میکنند:
CancelOrder
GetOrder
UpdateOrder
منطق فقط در یک مکان زندگی میکند.
این نکتهٔ مهم را نشان میدهد:
ءSliceهای مختلف میتوانند Domain Model یکسانی را به اشتراک بگذارند.
Tier 3: Feature-Specific Logic (محلی نگه دارید) 📌
منطق مشترک بین Sliceهای مرتبط — مانند CreateOrder و UpdateOrder — نیازی ندارد که Global شود.
میتوانید یک فولدر کوچک Shared در داخل یک Feature ایجاد کنید:
📂 Features
└──📂 Orders
├──📂 CreateOrder
├──📂 UpdateOrder
├──📂 GetOrder
└──📂 Shared
├──📄 OrderValidator.cs
└──📄 OrderPricingService.cs
این یک مزیت پنهان هم دارد:
اگر یک روز Feature مربوط به Orders را حذف کنید، Shared logic مخصوص آن هم حذف میشود.
هیچ کد مردهای (Zombie Code) باقی نمیماند. 🧟♂️❌
اشتراکگذاری بین Featureهای مختلف 🚦
در Vertical Slice Architecture، اشتراکگذاری کد بین Featureهای نامرتبط چطور انجام میشود؟
ءCreateOrder باید بررسی کند آیا Customer وجود دارد یا نه.GenerateInvoice باید Tax را محاسبه کند.Orders و Customers هر دو باید پیامهای Notification را فرمت کنند.
اینها در یک فولدر Shared مخصوص Feature جا نمیگیرند. پس کجا باید بروند؟
اول، بپرسید: آیا واقعاً نیاز به اشتراکگذاری وجود دارد؟
بیشتر اشتراکگذاریهای cross-feature در واقع Data Access در پوشش جدید هستند.
اگر CreateOrder به اطلاعات Customer نیاز دارد، باید مستقیماً دیتابیس را Query کند.
نباید Feature مربوط به Customers را صدا بزند.
هر Slice مالک دسترسی به دادههای خودش است.Entity مربوط به Customer Shared است (در Domain قرار دارد)،
اما Service اشتراکی بین آنها وجود ندارد.
وقتی واقعاً نیاز به اشتراکگذاری منطق دارید، بپرسید ماهیت آن چیست:
اگر Domain Logic است (Business Rules یا Calculations) → Domain/Services
اگر Infrastructure است (APIهای خارجی، Formatting) → Infrastructure/Services
نمونه:
// Domain/Services/TaxCalculator.cs
public class TaxCalculator
{
public decimal CalculateTax(Address address, decimal subtotal)
{
var rate = GetTaxRate(address.State, address.Country);
return subtotal * rate;
}
}
هم CreateOrder و هم GenerateInvoice میتوانند از آن استفاده کنند بدون اینکه به هم Coupled شوند.