Entity Framework und Layer-Trennung

12

Ich versuche ein bisschen mit Entity Framework zu arbeiten und habe eine Frage bezüglich der Trennung von Ebenen.

Ich benutze normalerweise den UI -> BLL -> DAL-Ansatz und frage mich, wie ich EF hier verwenden soll.

Mein DAL wäre normalerweise so ähnlich

GetPerson(id)
{
    // some sql
    return new Person(...)
}

BLL:

GetPerson(id)
{
    Return personDL.GetPerson(id)
}

Benutzeroberfläche:

Person p = personBL.GetPerson(id)

Meine Frage ist nun: Da EF mein Modell und mein DAL erstellt, ist es eine gute Idee, EF in mein eigenes DAL zu packen, oder ist es nur Zeitverschwendung?

Wenn ich EF nicht umbrechen muss, würde ich meine Model.esmx trotzdem in eine eigene Klassenbibliothek einfügen oder wäre es in Ordnung, sie einfach in meine BLL einzufügen und dort einige zu bearbeiten?

Ich kann den Grund nicht wirklich erkennen, EF in meine eigene DAL zu packen, aber ich möchte wissen, was andere Leute tun.

Anstatt das oben Genannte zu haben, würde ich die DAL weglassen und einfach tun:

BLL:

GetPerson(id)
{
    using (TestEntities context = new TestEntities())
    {
            var result = from p in context.Persons.Where(p => p.Id = id)            
                    select p;
    }
}

Was ist zu tun?

Thomas
quelle

Antworten:

13

Das Beispiel, das Sie zur Verfügung stellen, ist kaum geschichtete Architektur. Ich weiß, dass es absichtlich vereinfacht wurde, aber:

Ihre Präsentationsebene ist direkt an die Entität Person gebunden. Dies ist nur in den einfachsten Fällen in Ordnung und definitiv nicht, wenn Sie versuchen, Ihre Ebenen zu definieren.

Die GetPerson-Methode verwendet außerdem eine ziemlich schlechte Methode zum Erstellen eines neuen Kontexts für jeden Aufruf. Sie sollten den Kontext im Konstruktor abrufen, und er wird von Ihrem IOC-Container bereitgestellt.

Eine einfache, aber effektive Struktur, die ich verwendet habe, ist:

  • Project.Core - enthält Ansichtsmodelle und Schnittstellen.
  • Project.DAL - mit meinem EDMX und generierten Code.
  • Project.BLL - Geschäftslogik.
  • Project.Web - die Web-App selbst.

Es ist wichtig sich das zu merken:

  • Core ist von keiner anderen Lösung abhängig.
  • DAL ist von keiner anderen Lösung abhängig.
  • Project.Web ist abhängig von Core, aber nicht von DAL oder BLL.
  • BLL hängt von Core und DAL ab.
Boris Yankov
quelle
1
Kern scheint eine Geschäftsobjektschicht zu sein.
sq33G
Dies ist so ziemlich das, was ich auch benutze, ich würde jedoch zusätzliche DLLs hinzufügen, um Schnittstellendeklarationen zu berücksichtigen. Auf diese Weise referenzieren Sie nur die Schnittstellen (und verwenden für DI so etwas wie [url = unity.codeplex.com/[/url] ), und Sie können sicher sein, dass es keine seltsamen Abhängigkeiten gibt, die Sie versehentlich induziert haben.
Ed James
Normalerweise erstelle ich ohne EF meine eigene Personenklasse in einer "Modell" -Ebene, also habe ich UI, BLL, DAL und Model, wobei UI BLL und Model kennt. BLL kennt DAL und Model. DLL kennt Model. Erstellen Sie auch Ihre eigenen "Ansichtsmodelle" und warum verwenden Sie nicht nur die von EF generierten? (Ich weiß, dass dies gegen die geschichtete Architektur verstößt, aber wie oft wechseln Sie tatsächlich die Art und Weise, wie Sie Daten erhalten?)
Thomas
@Thomas, das die Ansichtsmodelle in etwas Abstraktes einwickelt , vereinfacht das Testen von Einheiten erheblich.
sq33G
3
model! = Modell ansehen
Boris Yankov
2

Sie müssen Ihr EDMX in nichts einwickeln.

Wenn Sie die Möglichkeit eines Wechsels von EF zu einem anderen Ansatz vorhersehen können, möchten Sie möglicherweise Ihre Geschäftsobjekte (unter Ausnutzung der Teilklassen) erweitern, um Schnittstellen zu implementieren, die in einer separaten Geschäftsobjektschicht definiert sind.

Dann beschäftigen Sie sich in Ihrem Code nur mit diesen Schnittstellen und nicht mit den konkret generierten Klassen. Möglicherweise ist ein kleiner Klebercode erforderlich, um dies zusammenzuhalten. das mit dem EDMX kann dein DAL sein.

sq33G
quelle
Also, wenn ich keine Änderungen von EF zu einem anderen Ansatz forciere, wäre mein Code oben in Ordnung? Ich hätte dann nur UI und BLL (wo ist die EDMX in der BLL)?
Thomas
Meine pragmatische Antwort wäre ja. Mit dem Vorbehalt, dass Sie den EDMX tatsächlich in eine eigene kleine Baugruppe einbauen möchten, wenn er groß und größtenteils statisch ist, sodass Sie ihn nicht so oft neu kompilieren / verteilen müssen.
sq33G
Ah, ein guter Punkt zum Neukompilieren / Weiterverteilen :)
Thomas
2

Es gibt zwei allgemeine Herangehensweisen an die Schichtung: strikte Schichtung und entspannte Schichtung.

Bei einem streng geschichteten Ansatz müssen die Komponenten in einer Ebene nur mit Gleichaltrigen und mit der direkt darunter liegenden Ebene interagieren.

Bei einer entspannten Anwendung mit mehreren Ebenen werden die Einschränkungen gelockert, sodass eine Komponente mit Komponenten aus einer beliebigen unteren Ebene interagieren kann.

Die Verwendung einer entspannten Schichtung kann die Effizienz verbessern, da das System einfache Anrufe nicht von einer Schicht zur nächsten weiterleiten muss. Auf der anderen Seite bietet die Verwendung einer entspannten Schichtung nicht das gleiche Maß an Isolation zwischen den Schichten und macht es schwieriger, eine niedrigere Schicht auszutauschen, ohne die höheren Schichten zu beeinträchtigen.

Bei großen Lösungen mit vielen Softwarekomponenten ist es üblich, eine große Anzahl von Komponenten auf derselben Abstraktionsebene zu haben, die nicht zusammenhängend sind. In diesem Fall kann jede Schicht weiter in ein oder mehrere zusammenhängende Teilsysteme zerlegt werden. Abbildung 2 zeigt eine mögliche UML-Notation (Unified Modeling Language) zur Darstellung von Ebenen, die aus mehreren Subsystemen bestehen.

Fazit: Wenn Sie die mittlere Schicht nicht brauchen, verlieren Sie sie; Nicht alle Anwendungen erfordern den gleichen Ansatz, und das Hinzufügen eines Layers nur zum Zwecke des Layerns wirkt sich nachteilig auf die Komplexitätskosten und die Wartung aus.

omarqa
quelle