C# - Service-Layer-Design-Muster
Suchen wir in erstellen ein neues Projekt und wollen zu erkunden mit dem Repository und Service-layer-Muster, das Ziel ist das erstellen von lose gekoppelten code vollständig getestet mit mock-repositories.
Unten finden Sie die grundlegende Architektur Idee. Wir werden über Schnittstellen zu beschreiben, die repositories und injizieren diese in den service-Layer zu entfernen Sie alle Abhängigkeiten. Dann mit autofac wir Draht, die services zur Laufzeit.
public interface IOrderRepository
{
IQueryable<Order> GetAll();
}
public class OrderRepository : IOrderRepository
{
public IQueryable<Order> GetAll()
{
return new List<Order>().AsQueryable();
}
}
public class OrderService
{
private readonly IOrderRepository _orderRepository;
public OrderService(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
public IQueryable<Order> GetAll()
{
return _orderRepository.GetAll();
}
}
public class EmailService
{
public void SendEmails()
{
//How do I call the GetAll method from the order serivce
//I need to inject into the orderService the repository to use
}
}
Gibt es ein paar Fragen, die wir Schwierigkeiten haben, herauszufinden, der beste Weg nach vorn.
1) Sollte der service sein, die Reproduktion der CRUD-Methoden, wie es scheint, können wir reproduzieren code ohne wirklichen nutzen. Oder sollte die Benutzeroberfläche rufen Sie die repositories direkt?
2) Was passiert, wenn ein Dienst braucht, um einen anderen Dienst. In unserem Beispiel oben, wenn die E-Mail-Dienst braucht, um all die Aufträge, die wir injizieren die um-service in der E-Mail-service?
Hoffe, das macht Sinn
Was macht Ihr, um Dienst zu tun? Nur Kapseln die OrderRepository? Oder muss er mehr tun, als die, aus der sieht der code es scheint nur, wie eine redundante layer.
Ich würde eine andere Frage stellen. Ist es gut, zu entlarven IQueryable<T> außerhalb der repository-Grenze ? Für mich nicht. Es ist ein leaky abstraction.
IQueryable<T> ist völlig mockable?
ja, aber das ist nicht der Punkt
InformationsquelleAutor user1223218 | 2012-02-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
E-Mail-service sollte nicht bewusst sein, Dienste wie OrderService, müssen Sie Mediator, um die Arbeit mit E-Mail&&Dienstleistungen, so würden Sie entkoppelt, oder Adapter anzupassen
IOrder
zuIEmail
:Vermittler:
Adapter:
Hi, danke für dein feedback. In dem Beispiel oben, wäre das SendEmails Methode? Würden Sie nicht auch noch brauchen-code irgendwo die bekommt die Aufträge und ruft dann die E-Mail-service?
dies könnte ein Vermittler. Unter Berücksichtigung der Anforderungen yu haben, wer ist die Bestimmung, wenn eine Zeit zu nennen
SendEmails()
, wird es einige event-handler?Danke, was sind Ihre Gedanken über die Reproduktion von code, so dass der service-Layer geht über den CRUD-Befehle, um die repositories? Wenn fühlt sich redundant, aber gleichzeitig offener für Veränderungen in der Zukunft.
siehe folgende Diskussion CRUD-Schnittstelle für eine Service - Ist eine schlechte Praxis ?
InformationsquelleAutor sll
Werfen Sie einen Blick auf Domain-Driven Design. DDD bewegt Großteil der Logik in den Entitäten (
Order
,Email
) und ermöglicht Ihnen die Nutzung der repositories.Einen Dienst in DDD wird verwendet, wenn Sie finden, sich selbst dem schreiben der business-Logik außerhalb der Entitäten.
Injizieren es in den Konstruktor. Aber der service sollte senden Sie eine E-Mail, nicht die andere Weise herum.
Den DDD Ansatz wäre eine
OrderNotificationService
welche die Domäne-EreignisOrderCreated
und schreibt eine E-Mail, die sendet er durch dieEmailService
Update
Du mich missverstanden. Duplizierte Logik ist nie gut. Würde ich nicht eine Methode, die in meinem Dienst mit dem Namen
GetAll
wenn mein repository hat. Weder würde ich diese Methode in meine Person.Beispiel-code:
Order.Send()
sollte eine Domäne erstellen, Veranstaltung, dass dieOrderNotificationService
fangen kann.Update2
Repository.Create
ist nur eine Fabrik-Methode (googlefactory method pattern
), um alle Domänen-Modell-Kreationen in einem Ort. Sie tun nichts in die db (auch wenn Sie es in zukünftigen Versionen).Als für Ordnung.Speichern Sie es verwenden würde, das repository zu speichern, um alle Linien, die um sich selbst oder irgendetwas anderes, die notwendig wären.
+1 - OrderNotificationService klingt auf jeden Fall mehr wie der richtige Weg zu mir.
Lies mein update.
Hi, tut repository.Erstellen Sie eine Bestellung zurücksenden? Wenn ja wie funktioniert die Bestellung.Speichern verwenden Sie das repository. Vielen Dank für Ihre Hilfe.
Ein neues update.
InformationsquelleAutor jgauffin
Was ich gemacht hätte, ist
Nicht nennen-repositories direkt aus der UI, sondern rufen Sie die service statt und der Dienst sollte mit dem repository,
Ich würde den Aufruf der Methode, Um repository von E-Mail-service, auf diese Weise hätte ich nur zu injizieren OrderRepository zu E-Mail-Service (kein Service)
InformationsquelleAutor Jayanga
können Sie adapter-Muster oder mit DI-tools
InformationsquelleAutor hanz