8

Ich hatte eine Infrastruktur für unser brandneues Intranet-Projekt geschaffen und versucht, fast allen Best Practices zu folgen. Ich möchte auch erwähnen, dass dies das erste Mal ist, dass ich eine Architektur von Null an erstellt habe.Implementieren von begrenztem Kontext in Entity Framework-basierte Infrastruktur

Momentan ist die erste Version meiner Infrastruktur fertig und funktioniert gut. Aber ich möchte beschränkte Kontextstruktur in der nächsten Version implementieren.

Ich versuchte, die folgende Situation zu erklären.

DbCore: verantwortlich für Datenoperationen. Entity Framework 5 Code Zuerst verwendet. Es gibt nur eine DbContext-Klasse und alle darin definierten DbSets. Auch GenericRepository-Muster und Unit of Work-Muster wurden anhand der folgenden Schnittstellen implementiert.

IGenericRepository

public interface IGenericRepository<TEntity> 
    where TEntity : class { 
     void Delete(object id); 
     void Delete(TEntity entityToDelete); 
     System.Collections.Generic.IEnumerable<TEntity> Get(System.Linq.Expressions.Expression<Func<TEntity, bool>> filter = null, Func<System.Linq.IQueryable<TEntity>, System.Linq.IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = ""); 
     System.Collections.Generic.IEnumerable<TEntity> GetAll(); 
     TEntity GetByID(object id); 
     System.Collections.Generic.IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters); 
     void Insert(TEntity entity); 
     void Update(TEntity entityToUpdate); 
    } 

IUnitOfWork

public interface IUnitOfWork { 
     void Dispose(); 
     IGenericRepository<Test> TestRepository { 
      get; 
     } 
     IGenericRepository<Log> LogRepository { 
      get; 
     } 
     void Save(); 
    } 

Modelle: Verantwortlich Speichereinheit Modelle für DbCore und Entity Framework Domain: Repräsentieren Business-Logik-Schicht speichert auch DTOs für Entität Objekte, die im Models-Projekt gespeichert wurden. Aktuelle Geschäftslogik in Service-Klasse gespeichert, die Schnittstelle folgende implementiert IService

public interface IService<TEntity> { 

     IEnumerable<TEntity> Get(); 
     TEntity GetByID(int id); 
     void Insert(TEntity entity); 
    } 

Dieser Service Klasse bekommt UnitOfWork über Ctor Parameter und für Operationen verwenden. Auch Automapper implementiert, um Entitätsobjekte in DTOs umzuwandeln oder umgekehrt. Ab jetzt sind alle oberen Schichten nicht mehr an Entitätsmodellen interessiert, sondern verwenden nur DTOs. Daher beziehen sich fast alle Projekte (einschließlich API und Web) auf dieses Projekt.

Häufig: Verantwortlich für das Speichern von häufig verwendeten Bibliotheken wie Protokollierung.

WebCore: Verantwortlich für die Speicherung häufig verwendeter Bibliotheken für webbasierte Projekte wie API oder MVC. Enthält auch Erweiterungen, Handler und Filter für MVC-basierte Projekte.

API: ASP.Net MVC-Web-API-Projekt stellt Service-Layer dar. Verbraucht Domänenebene und dient Clients. Controller ruft die IService-Schnittstelle als ctor-Parameter ab und verwendet sie, um auf die Datenebene durch die Domänenebene zuzugreifen.

Web: ASP.Net MVC 4 basiert Webprojekt, verantwortlich mit Interaktion mit Benutzer. Verbraucht API-Methoden für den Zugriff auf Daten. Alle Controller erhalten eine Schnittstelle namens IConsumeRepository, die die API über HttpClient verbindet.

public interface IConsumeRepository<TEntity> { 
     Task<TEntity> Create(TEntity TestInfo); 
     Task Delete(int id);  
     Task<IEnumerable<TEntity>> Get(); 
     Task<TEntity> Get(int id); 
     TEntity New();  
     Task<TEntity> Update(TEntity TestInfo, int entityId); 
    } 

Autofac ist verantwortlich für IoC und DI für alle Projekte.

Für jetzt ist dies meine aktuelle Infrastruktur, ich denke, ich habe alles erklärt, was bewertet werden muss.

Jetzt versuche ich, folgende Dinge herauszufinden

Frage 1: Gibt es etwas, das so, wie ich verwendet werden darf nicht impelemented?

Frage 2: Was ist der beste Ansatz, um gebundene Kontexte zu implementieren? Ich habe kürzlich Julie Lerman's Videos angeschaut und viele Beispielprojekte besprochen. Was ich gesehen habe, war, dass ich BC von DbContext abgeleitet habe. Aber ich konnte mir nicht sicher sein. Weil ich gedacht hatte, BCs sollten in der Domäne (Geschäftslogik) Schicht nicht in DbCore (Datenzugriff) Schicht sein.

Frage 3: Wie ich oben erwähnt, meine Api und Web-Projekte verwendet DTOs, so dass beide Referenzen Domain Layer haben müssen. Aber ich mochte es nicht, weil ich Business-Schicht von der Benutzeroberfläche mit einer API getrennt und sie wieder für Entitäten gekoppelt habe. Aber ich konnte keinen besseren finden.

Dies wurde eine lange Frage, aber ich werde sehr glücklich sein, wenn Sie Ihre Ideen mit mir teilen, um bessere Architektur zu erstellen.

Antwort

30

Frage 1: Angenommen, Sie haben eine komplexe Geschäftsdomäne und eine signifikante Geschäftslogik, kann es sich lohnen, die Domänenschicht von Infrastrukturproblemen zu isolieren. Dies ist jedoch oft nicht der Fall. Wenn Sie Daten nur aus der Datenbank in die Benutzeroberfläche und wieder zurück verschieben, ist dies überdimensioniert und Sie sollten etwas mit weniger beweglichen Teilen suchen.

Frage 2: Wie viele verschiedene Domänenmodelle (mit verschiedenen ubiquitären Sprachen) haben Sie? Ein? Zwei? Drei? Isolieren Sie sie für jedes Modell so weit wie möglich von anderen Modellen und Infrastrukturproblemen.

Eric Evans definiert einen begrenzten Kontext als in erster Linie eine sprachlichen Grenze (Zitat aus seinem Buch):

ein beschränktes CONTEXT die Anwendbarkeit eines bestimmten Modells begrenzt so dass die Teammitglieder haben eine klare und gemeinsames Verständnis darüber, was konsistent zu sein hat und wie es sich auf andere CONTEXTS bezieht. Innerhalb dieser CONTEXT, arbeiten, um das Modell logisch einheitlich zu halten, aber keine Sorge über die Anwendbarkeit außerhalb dieser Grenzen. In anderen CONTEXTS gelten andere Modelle, mit Unterschieden in der Terminologie, in Konzepten und Regeln, und in Dialekten der UBIQUITOUS LANGUAGE.

DbContext Sie in die richtige Richtung zeigen kann, aber nicht vergessen, es ein Artefakt Infrastruktur ist, nicht ein Domain-Konzept. Es "stellt eine Kombination der Arbeitseinheits- und Repository-Muster dar und ermöglicht es Ihnen, eine Datenbank abzufragen und Änderungen zusammenzufassen, die dann als Einheit in den Speicher zurückgeschrieben werden." _ (Von MSDN Docs).

DDD ist über Domänenmodellierung: Verwenden von Modellen zur Lösung schwieriger Geschäftsprobleme in komplexen Geschäftsbereichen. Das Ableiten von Modellgrenzen aus technischen Überlegungen kann sich wie der Schwanz wedeln lassen. Definieren Sie konzeptionell die Grenze Ihres Modells und richten Sie Ihre technische Infrastruktur entsprechend aus.

Frage 3: DTOs können eine gute Möglichkeit sein, eine Kontextgrenze zu erzwingen, wie für eine API. Die API kann dann als Anti-Korruptionsschicht für andere Modelle fungieren. Der Grund, warum Benutzer sie normalerweise für Benutzeroberflächen verwenden, besteht darin, zu vermeiden, dass Benutzeroberflächenkonzepte in das Domänenmodell kopiert werden müssen.

Suchen Sie keine perfekte Architektur. Und erkennen, dass "Best Practices" wirklich nur Richtlinien sind, die auf bestimmten Situationen basieren. Befolgen Sie die Richtlinien, die andere erfahrenere Personen aufgestellt haben, mit dem Verständnis, dass Ihre Situation wahrscheinlich subtil anders ist. Verwenden Sie, was Sie haben mit der Erwartung, Ihre Design-Entscheidungen zu refaktorisieren, wenn Sie Reibung finden. Wenn Sie beispielsweise später feststellen, dass die DTOs auf der Benutzeroberfläche übertrieben sind, entfernen Sie sie. Vereinfachen Sie, wo immer Sie können.

+8

möchte hier ein paar hundert mal +1 klicken können! –