Application Serviceها هر آنچه برای انجام یک Use-case نیاز است را در دل خود دارند به عنوان مثال:
[HttpPost, AjaxOnly, ValidateAntiForgeryToken, ValidateModelState]
public virtual async Task<ActionResult> Create([Bind(Prefix = "Model")]MeetingCreateModel model)
{
await _service.CreateAsync(model).ConfigureAwait(false);
return InformationNotification("Messages.Save.Success");
}
صحبت شما کاملا درست است ولی زمانی که به عنوان مثال بخشی از منطق تجاری اصلی در بالاترین لایه هم قرار میگرفت.
فرض کنید، برای ثبت یک جلسه نیاز است این اعتبارسنجی انجام شود که مدعوین انتخاب شده از حیث جایگاه خود در ساختار سازمانی امکان انتخاب شدن به عنوان مدعو توسط کاربر جاری را داشتند یا خیر؛ مکان این اعتبارسنجی قطعا لایه سرویس میباشد. چه بسا در این اعتبارسنجی کوئریهای مختلفی اجرا شود که خروجی Null هم داشته باشند و مشکلی هم ندارد و من هم روی این خروجیها بررسی شرطی انجام میدهم ولی اینها همه در دل متد CreateAsync قرار دارند یا برای آنها Validator مناسب در نظر گرفته شده است. صحبت این است که این متد اگر خود یک استثنا صادر نکند، باید یک OperationResult بازگشت دهد و نهایتا این خطاها به ModelState اضافه شوند برای نمایش به کاربر نهایی. من استثنا صادر میکنم و آن را گرفته و هم میتوانم به خطاهای ModelState اضافه کنم یا به عنوان پاسخ یک درخواست Ajax ای استفاده کنم.
Actionهای لایه Presentation مورد نظر من هیچ کاری انجام نمیدهند؛ برای مثال اگر قرار است یکسری برچسب به یک مطلب اضافه شود این قضیه که کدام یک قبلا بودن یا جدید هستند و از این قبیل کارها در دل متد مثلا Create مرتبط با مطلب یا ویرایش آنها صورت میگیرد و در واقع در پیاده سازی آنها همان بررسی Null بودن یا این چنین بررسیها انجام خواهد گرفت قطعا.
صحبت نهایی اینکه Application Serviceهای مورد نظر من هر آنچه نیاز است را برای انجام یک use-case انجام خواهند داد و واقعا به عنوان مدخل ورودی سیستم عمل میکنند. حال مدخل ورودی سیستم مورد نظر شما شاید همان بالاترین لایه یا خارجیترین آن باشد که در آن صورت قضیه متفاوت میباشد.