Ich entwerfe derzeit eine n-Tier-Lösung, die Entity Framework 5 (.net 4) als Datenzugriffsstrategie verwendet, bin jedoch besorgt darüber, wie die Abhängigkeitsinjektion integriert werden kann, um sie testbar / flexibel zu machen.
Mein aktuelles Lösungslayout sieht wie folgt aus (meine Lösung heißt Alcatraz):
Alcatraz.WebUI : Ein asp.net-Webform-Projekt, die Front-End-Benutzeroberfläche, verweist auf die Projekte Alcatraz.Business und Alcatraz.Data.Models .
Alcatraz.Business : Ein Klassenbibliotheksprojekt, enthält die Geschäftslogik, verweist auf Projekte Alcatraz.Data.Access , Alcatraz.Data.Models
Alcatraz.Data.Access : Ein Klassenbibliotheksprojekt, das AlcatrazModel.edmx und AlcatrazEntities
DbContext enthält, verweist auf Projekte Alcatraz.Data.Models .
Alcatraz.Data.Models : Ein Klassenbibliotheksprojekt, enthält POCOs für das Alcatraz-Modell, keine Referenzen.
Meine Vision für die Funktionsweise dieser Lösung ist, dass die Web-Benutzeroberfläche ein Repository innerhalb der Geschäftsbibliothek instanziiert und dieses Repository eine Abhängigkeit (über den Konstruktor) von einer Verbindungszeichenfolge (keine AlcatrazEntities
Instanz) aufweist. Die Web-Benutzeroberfläche würde die Datenbankverbindungszeichenfolgen kennen, aber nicht, dass es sich um eine Entity Framework-Verbindungszeichenfolge handelt.
Im Business-Projekt:
public class InmateRepository : IInmateRepository
{
private string _connectionString;
public InmateRepository(string connectionString)
{
if (connectionString == null)
{
throw new ArgumentNullException("connectionString");
}
EntityConnectionStringBuilder connectionBuilder = new EntityConnectionStringBuilder();
connectionBuilder.Metadata = "res://*/AlcatrazModel.csdl|res://*/AlcatrazModel.ssdl|res://*/AlcatrazModel.msl";
connectionBuilder.Provider = "System.Data.SqlClient";
connectionBuilder.ProviderConnectionString = connectionString;
_connectionString = connectionBuilder.ToString();
}
public IQueryable<Inmate> GetAllInmates()
{
AlcatrazEntities ents = new AlcatrazEntities(_connectionString);
return ents.Inmates;
}
}
In der Web-Benutzeroberfläche:
IInmateRepository inmateRepo = new InmateRepository(@"data source=MATTHEW-PC\SQLEXPRESS;initial catalog=Alcatraz;integrated security=True;");
List<Inmate> deathRowInmates = inmateRepo.GetAllInmates().Where(i => i.OnDeathRow).ToList();
Ich habe ein paar verwandte Fragen zu diesem Design.
Ist dieses Design in Bezug auf die Entity Frameworks-Funktionen überhaupt sinnvoll? Ich habe gehört, dass das Entity-Framework bereits das Unit-of-Work-Muster verwendet. Füge ich nur unnötigerweise eine weitere abstrakte Ebene hinzu?
Ich möchte nicht, dass meine Web-Benutzeroberfläche direkt mit Entity Framework kommuniziert (oder auch nur darauf Bezug nimmt). Ich möchte, dass der gesamte Datenbankzugriff über die Business-Schicht erfolgt, da in Zukunft mehrere Projekte auf derselben Business-Schicht ausgeführt werden (Webservice, Windows-Anwendung usw.) und ich möchten, dass die Geschäftslogik in einem zentralen Bereich verwaltet / aktualisiert werden kann. Ist dies ein geeigneter Weg, um dies zu erreichen?
Sollte die Business-Schicht überhaupt Repositorys enthalten, oder sollte diese in der Access-Schicht enthalten sein? Wenn es in Ordnung ist, wo sie sich befinden, ist die Übergabe einer Verbindungszeichenfolge eine gute Abhängigkeit, die anzunehmen ist?
Vielen Dank, dass Sie sich die Zeit zum Lesen genommen haben!
DbContext
als seine Abhängigkeit. Die Geschäftsklassen haben Repositorys als Abhängigkeit. Für die Abhängigkeitsinjektion mache ich dies manuell (damit ich verstehe, was los ist). Der Grund, warum ich die Verbindungszeichenfolge in festlegen möchte,DbContext
ist, dass ich Datenbank-Sharding verwende. In bestimmten Fällen muss ich über ein Entity-Framework verfügen, um eine Verbindung zu verschiedenen Datenbanken (mit derselben Struktur) herzustellen . Verstehe ich dich richtigEin paar kurze Kommentare. Ich persönlich würde wahrscheinlich keine Verbindungszeichenfolge übergeben. Wenn überhaupt würde ich versuchen, Schnittstellen möglicherweise für die Behälter zu verursachen und die Schnittstellen gerade herum zu führen? Lassen Sie die Repositorys eine IOW-Schnittstelle implementieren oder verfügbar machen.
Auf diese Weise muss es sich nicht unbedingt um eine Datenbank handeln, die Ihre Repositorys implementiert. Es könnte sich um einen Cache im Speicher handeln oder um etwas anderes. Vielleicht könnten Sie dann eine Art Abhängigkeitsinjektions-Framework verwenden, um diese sogar zu instanziieren?
Also als Antwort auf einige Ihrer Fragen:
Dies sind nur ein paar Gedanken zum Nachdenken.
quelle