Bir kontrolörün doğrudan bir havuzu çağırması kötü bir uygulama değildir. Bir "servis" sadece başka bir araçtır, bu yüzden mantıklı olduğu yerde kullanın.
NikolaiDante yorum yaptı:
... Doğru uygulama için doğru deseni seçin. Söyleyeceğim şey, başvurunuzu tutarlı hale getirmeniz gerektiği.
Tutarlılığın en önemli yönü olduğunu sanmıyorum. Bir "servis" sınıfı, bazı üst seviye mantıkları kapsamaya yöneliktir, böylece kontrol cihazının bunu uygulamasına gerek kalmaz. Belirli bir işlem için gerekli hiçbir "üst seviye mantık" yoksa, doğrudan depoya gidin.
Ayrı Endişelerin ve Test Edilebilir Ayrımın teşvik edilmesi için, depo, bir yapıcı aracılığıyla servise enjekte ettiğiniz bir bağımlılık olmalıdır:
IFooRepository repository = new FooRepository();
FooService service = new FooService(repository);
service.DoSomething(...);
Veritabanındaki kayıtları aramak bir tür parametreli sorguya ihtiyaç duyuyorsa, hizmet sınıfı görünüm modelinizi almak ve daha sonra depo tarafından yürütülen bir sorgu oluşturmak için iyi bir yer olabilir.
Benzer şekilde, bir form için karmaşık bir görünüm modeline sahipseniz, bir hizmet sınıfı, Etki Alanı Modelleri / Varlıklarınızdaki yöntemleri çağırarak kayıtlar oluşturma, güncelleme ve silme mantığını kapsayabilir ve daha sonra bunları bir depo kullanarak devam ettirebilir.
Eğer kontrol cihazınızın kimliği ile bir kayıt alması gerekiyorsa, ters yönlere gitmek, o zaman bunun için bir servis nesnesine yetki vermek, bir balyozla raptiye vurmak gibidir - ihtiyaç duyduğunuzdan çok daha fazlası.
İşlemi veya bir Birim Birimi nesnesini işlem yapmak için denetleyicinin en iyi konumda olduğunu buldum . Kontrolör veya Çalışma Birimi nesnesi daha sonra karmaşık işlemlerde servis nesnelerine devreder veya basit işlemler için doğrudan depoya gider (Id ile kayıt bulma gibi).
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);
}
}
}
}
Bence bir hizmet karışımı ve doğrudan depolarla çalışmak tamamen kabul edilebilir. İhtiyacı hissederseniz, işlemi bir İş Birimi nesnesinde daha fazla kapsülleyebilirsiniz.
Sorumlulukların dağılımı şu şekildedir:
- Kontrolör uygulamanın akışını kontrol eder
- Alışveriş sepeti veritabanında değilse "404 Bulunamadı" ifadesini döndürür
- Doğrulama başarısız olursa, formu doğrulama mesajlarıyla yeniden işler
- Her şey kontrol edilirse alışveriş sepetini kaydeder
- Denetleyici, Etki Alanı Modellerinizde (veya Varlıklar) iş mantığını yürütmek için bir hizmet sınıfına yetki verir. Hizmet nesneleri iş mantığını uygulamamalıdır ! Onlar yürütmek iş mantığını.
- Kontrolörler basit işlemler için doğrudan depolara devredebilir
- Hizmet nesneleri görünüm modelinde veri alır ve iş mantığını yürütmek için Etki Alanı Modellerine yetki verir (örn. Hizmet nesnesi, depodaki yöntemleri çağırmadan önce Etki Alanı Modellerinde yöntemleri çağırır)
- Hizmet nesneleri veri kalıcılığı için depolara devrediyor
- Kontrolörler şunlardan birini yapmalıdır:
- Bir işlemin ömrünü yönetme veya
- Bir işlemin ömrünü yönetmek için İş Birimi nesnesi oluşturma