c# - geschäftslogik - mvc business logic




Business-Logik-Ebene und Datenzugriffsebene: Kreisabhängigkeit (6)

DAL muss abstrakt sein, daher muss es nur einfache ADO.NET-Objekte enthalten, die mit der Backend-Datenbank interagieren, z. B. Verbindung DataAdapter, DataReader und so weiter. Damit können Sie DAL in Ihrer Biz-Schicht referenzieren, und wenn Sie mit ein wenig Abstraktion zu Ihren Entitäten kommen, können Sie all Ihre Probleme lösen, zum Beispiel wenn Sie eine Kundenklasse haben, können Sie eine Kundenklasse abstaraacto machen, die die implementieren grundlegende Operationen zur Interaktion mit DAL wie das Speichern, Aktualisieren und Abrufen von Daten und in einer anderen Klasse, die die Abstraktionsklasse erbt, überschreiben die Implementierung der Basisklassenmethode, um Ihre Biz-Validierung usw. zu erfüllen.

Ich habe ein kleines Architekturproblem. In meinem Projekt habe ich einen Business-Logik-Layer (BLL), der alle meine Geschäftsregeln, Modelle und OO-API für die Schnittstelle enthält. Jedes Objekt verfügt über statische Methoden wie getById, die eine Instanz des Objekts zurückgeben. Jedes Objekt verfügt auch über Methoden wie Speichern und Löschen. Dies ist ein sehr einfacher OO-Code.

Jetzt habe ich einen DataAccess-Layer (DAL), der in einem separaten Namespace enthalten ist. Für jedes BLL-Objekt habe ich eine DataClass oder "Repository", die die Befehle getById und save ausführt. In gewisser Weise sind die Methoden BLL save und getById eine dünne Schicht um die DataClass-Methoden.

public static NewsItem GetByID(int id)
{
       return DataFactory.GetNewsItemRepository().GetNewsItemById(id);
}

Damit die DataClasses BLL-Objekte zurückgeben können, müssen sie die BLL kennen. So, jetzt haben wir:

GUI ---> BLL <----> DAL

Die DataFactory gibt nur Objekte zurück, die eine Schnittstelle implementieren, sodass ich Implementierungsdetails wie "OracleNewsItemRepository" ausblenden kann.

Aber jetzt für das, was mich seit dem Beginn der objektorientierten Programmierung nervt. In meiner gegenwärtigen Lösung müssen sich BLL und die DAL kennen. Dies ist eine zirkuläre Abhängigkeit, und es empfiehlt sich, zirkuläre Abhängigkeiten zu vermeiden. Außerdem möchte ich nur die Schnittstellen (und meine DataFactory) und nicht meine Klassen offen legen. Dies kann durch Platzieren der DAL-Schicht in einer separaten Baugruppe erfolgen. Was wäre sinnvoll. Visual Studio lässt jedoch nicht zu, dass sich zwei Assemblies gegenseitig verweisen. Eine andere Frage dazu: C # interne Zugriffsmodifikatoren

Irgendwie denke ich, dass ich mein gesamtes Datenzugriffsmuster falsch verstanden habe. Es fühlt sich an, als würde ich das ActiveRecord-Muster mit anderen Dingen wie DataMappers falten. Ich habe viel Zeit auf Martin Fowlers Seite verbracht, aber diese Muster sind sehr allgemein gehalten und werden durch ein sehr abstraktes UML-Diagramm illustriert.

Sie lösen mein Problem nicht. Vielleicht bin ich ein bisschen anal und es gibt kein "perfektes Datenzugriffsmuster". Und was ich jetzt tue, scheint nicht wirklich falsch zu sein. Aber wie ich jetzt Dinge mache, scheint aus ...

Irgendwelche Ideen?


Es ist jetzt ein bisschen alt, aber vielleicht hättest du darüber nachdenken sollen, die Pocos / Interfaces in eine andere Assembly zu legen.

Project.Data references Project.Entities
Project.BL references Project.Entities and Project.Data
Project.UI references Project.Entities and Project.BL

Hier gibt es keine Zirkelverweise.


Ich denke, Ihr Datenzugriffsmuster ist in Ordnung. Was Sie nicht tun, ist Ihre BLL mit dem OracleDAL zu koppeln. Sie koppeln an die DAL-Schnittstellen. Ein gewisses Maß an Kopplung ist absolut erforderlich oder Sie könnten nie etwas erreichen.

Ich nehme an, dass Ihre DataFactory- und die INewsItemRepository-Klassen außerhalb Ihrer DAL-Schicht existieren. Das folgende Beispiel zeigt, wie meine Lösungen organisiert sind. Ich verwende ActiveRecord nicht, daher passt das möglicherweise nicht perfekt zu Ihnen.

Core (Project)
  Domain
    Business Entities
  Data
    Repository Interfaces
    **Your DataFactory**

OracleData (Project)
  Data
    Oracle Repository Implementations

SqlData (Project)
  Data
    Sql Repository Implementations

UI (Project)

Hoffe das hilft.


Ich würde jede Methode Get () und Save () von Ihnen BLL (Domain-Modell) entfernen .. hier ist, was ich tun würde

Die GUI fragt das Repository nach dem Domain-Objekt per ID .. und sobald das GUI-Objekt das Domain-Objekt hat, können Sie es navigieren, um andere Objekte zu erreichen. Auf diese Weise braucht der Domain-Layer nichts über Repositories zu wissen.

Innerhalb des Repositorys können Sie Domänenobjekte zurückgeben, die das Objektobjekt grafisch laden oder vollständig laden. Das hängt von Ihnen ab.

Hier ist eine gute Zusammenfassung zum selben Thema ... Rekonstruieren von Objekten

Lesen Sie den Kommentar von Deyan Petrov über die Verwendung von dynamischem Proxy


Sie können Schnittstellen / Abhängigkeitsinjektion verwenden, um Ihr Problem zu lösen.

Ihre Business-Schicht (BL) enthält die Datenzugriff (DA) -Schnittstellen, die die (möglicherweise mehr als eine) DAL implementieren müssen. Die DAL-Projekte haben Projektreferenzen auf BL, so dass sie Business-Objekte (BOs) ausspeien und die DA-Schnittstellen implementieren können.

Ihre BOs können DataFactory aufrufen, wodurch ein DA-Objekt über die Abhängigkeitsinjektion oder -reflexion instanziiert werden kann.

Ich habe dieses Muster in vielen unserer Anwendungen hier bei der Arbeit (sowohl Web-basierte und Smart-Client) verwendet, und es funktioniert wunderbar.


Um es klar zu sagen: Ich denke an ein Geschäftsmodell und eine Geschäftslogik als zwei separate Ebenen. Ihr Geschäftsmodell sind Ihre POCOs (Plain Old CLR-Objekte). Ihre Business-Logik-Ebene würde für die Durchführung von Validierungen, Transaktionen usw. verantwortlich sein, die sowohl Ihr Geschäftsmodell als auch eine Schnittstelle zu Ihrem DAL verwenden, die auf verschiedene Arten verdrahtet werden kann (Spring, Castle oder Ihr eigener IoC-Container).

Eine gute Möglichkeit, in Ihrem DAL keine Abhängigkeiten zu Ihrem Geschäftsmodell zu erreichen, ist die Verwendung eines bereits bestehenden Object Relation Mapping Frameworks (ORM) wie NHibernate (ein schamloser Plug für mein bevorzugtes ORM-Framework).





architecture