ไม่ใช่วิธีปฏิบัติที่ไม่ดีสำหรับคอนโทรลเลอร์ที่จะเรียกที่เก็บโดยตรง "บริการ" เป็นเพียงเครื่องมืออื่นดังนั้นใช้งานในที่ที่เหมาะสม
NikolaiDante แสดงความคิดเห็น:
... เลือกรูปแบบที่เหมาะสมสำหรับแอพพลิเคชั่นที่เหมาะสม สิ่งที่ฉันจะพูดคือคุณควรทำให้ใบสมัครของคุณสอดคล้องกัน
ฉันไม่คิดว่าความมั่นคงเป็นสิ่งสำคัญที่สุด คลาส "เซอร์วิส" มีไว้เพื่อแค็ปซูลลอจิกระดับสูงขึ้นเพื่อให้คอนโทรลเลอร์ไม่จำเป็นต้องใช้มัน หากไม่มี "ตรรกะระดับสูงกว่า" ที่จำเป็นสำหรับการดำเนินการที่กำหนดให้ไปที่ที่เก็บโดยตรง
เพื่อส่งเสริมความกังวลและการทดสอบที่แยกจากกันได้ดีพื้นที่เก็บข้อมูลควรขึ้นกับที่คุณฉีดเข้าไปในบริการผ่าน Constructor:
IFooRepository repository = new FooRepository();
FooService service = new FooService(repository);
service.DoSomething(...);
หากการค้นหาเร็กคอร์ดในฐานข้อมูลต้องการเคียวรีแบบกำหนดพารามิเตอร์บางคลาสเซอร์วิสอาจเป็นที่ที่ดีที่จะใช้ในโมเดลมุมมองของคุณและสร้างเคียวรีที่ถูกเรียกใช้โดยที่เก็บ
หากคุณมีโมเดลมุมมองที่ซับซ้อนสำหรับฟอร์มคลาสเซอร์วิสสามารถสรุปแค็ปซูลลอจิกของการสร้างอัปเดตและลบระเบียนโดยวิธีการเรียกใช้ในแบบจำลองโดเมน / เอนทิตีของคุณจากนั้นใช้แบบพื้นที่เก็บข้อมูล
ไปในทิศทางตรงกันข้ามถ้าคอนโทรลเลอร์ของคุณจำเป็นต้องได้รับการบันทึกโดยใช้ ID จากนั้นการมอบหมายให้วัตถุบริการสำหรับสิ่งนี้ก็เหมือนกับการกดปุ่มตอกด้วยค้อนขนาดใหญ่ - มันมากกว่าที่คุณต้องการ
ฉันได้พบว่าการควบคุมอยู่ในตำแหน่งที่ดีที่สุดในการจัดการกับการทำธุรกรรมหรือหน่วยงานของวัตถุ จากนั้นวัตถุคอนโทรลเลอร์หรือหน่วยงานจะมอบหมายให้บริการวัตถุสำหรับการดำเนินการที่ซับซ้อนหรือไปที่ที่เก็บโดยตรงเพื่อการดำเนินการอย่างง่าย ๆ (เช่นการค้นหาระเบียนด้วย Id)
public class ShoppingCartsController : Controller
{
[HttpPost]
public ActionResult Edit(int id, ShoppingCartForm model)
{
// Controller initiates a database session and transaction
using (IStoreContext store = new StoreContext())
{
// Controller goes directly to a repository to find a record by Id
ShoppingCart cart = store.ShoppingCarts.Find(id);
// Controller creates the service, and passes the repository and/or
// the current transaction
ShoppingCartService service = new ShoppingCartService(store.ShoppingCarts);
if (cart == null)
return HttpNotFound();
if (ModelState.IsValid)
{
// Controller delegates to a service object to manipulate the
// Domain Model (ShoppingCart)
service.UpdateShoppingCart(model, cart);
// Controller decides to commit changes
store.SaveChanges();
return RedirectToAction("Index", "Home");
}
else
{
return View(model);
}
}
}
}
ฉันคิดว่าการผสมผสานของบริการและการทำงานกับที่เก็บข้อมูลโดยตรงนั้นเป็นที่ยอมรับอย่างสมบูรณ์ คุณสามารถสรุปธุรกรรมในวัตถุหน่วยงานได้หากคุณรู้สึกว่าต้องการ
การแบ่งความรับผิดชอบเป็นดังนี้:
- คอนโทรลเลอร์ควบคุมการไหลของแอปพลิเคชัน
- ส่งคืน "404 Not Found" หากตะกร้าสินค้าไม่ได้อยู่ในฐานข้อมูล
- แสดงฟอร์มอีกครั้งด้วยข้อความตรวจสอบความถูกต้องหากการตรวจสอบล้มเหลว
- บันทึกรถเข็นหากทุกอย่างเช็คเอาท์
- คอนโทรลเลอร์ได้รับมอบให้กับคลาสบริการเพื่อดำเนินการตรรกะทางธุรกิจในรูปแบบโดเมนของคุณ (หรือเอนทิตี) วัตถุบริการไม่ควรใช้ตรรกะทางธุรกิจ! พวกเขาใช้ตรรกะทางธุรกิจ
- ตัวควบคุมอาจมอบหมายโดยตรงไปยังที่เก็บสำหรับการดำเนินการอย่างง่าย
- วัตถุบริการใช้ข้อมูลในรูปแบบมุมมองและมอบให้แก่ Domain Models เพื่อดำเนินการตรรกะทางธุรกิจ (เช่นวิธีการเรียกใช้วัตถุบริการในรุ่นโดเมนก่อนที่จะเรียกวิธีการในพื้นที่เก็บข้อมูล)
- บริการวัตถุมอบหมายให้กับที่เก็บข้อมูลการคงอยู่ของข้อมูล
- ผู้ควบคุมควร:
- จัดการอายุการใช้งานของธุรกรรมหรือ
- สร้างหน่วยการทำงานของวัตถุเพื่อจัดการอายุการใช้งานของธุรกรรม