Implementing a context-limited infrastructure in an Entity Framework-based infrastructure

I built the infrastructure for our brand new intranet project and tried to follow almost all the best practices. I also want to mention that this is my first time to create architecture from scratch.

Currently my first version of the infrastructure is ready and working well. But I want to implement a limited context structure in the next version.

I tried to explain the current situation as follows.

DbCore: responsible for data operations. Entity Framework 5 Code First Used. It defines only one DbContext class and all DbSets. Also, the GenericRepository template and the Unit of Work template are implemented based on the following interfaces.

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(); } 

Models: Responsible storage entity models for DbCore and Entity Framework Domain:. At the business logic level, DTOs are also stored for entity objects that are stored in the Models project. Currently, business logic is stored in the Service class, which implemented the following IService interface

 public interface IService<TEntity> { IEnumerable<TEntity> Get(); TEntity GetByID(int id); void Insert(TEntity entity); } 

This service class receives UnitOfWork through the ctor parameter and is used for operations. Automapper is also implemented to convert object objects to DTO or vice versa. Now all top layers that are no longer interested in essential models use only DTO. Therefore, almost all projects (including api and web) refer to this project.

General: Responsible for storing commonly used libraries, such as journaling.

WebCore: Responsible for storing frequently used libraries for web projects such as APIs or MVCs. Also contains extensions, handlers, and filters for MVC-based projects.

Api: The ASP.NET MVC Web API project is a service layer. Uses a domain level and serves customers. The controllers receive the IService interface as the ctor parameter and use it to access the data layer through the domain layer.

Web: ASP.Net MVC 4-based web project responsible for user interaction. Consumes Api methods for accessing data. All controllers receive an interface called IConsumeRepository, which connects the API through an HttpClient.

  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 is responsible for IoC and DI for all projects.

While this is my current infrastructure, I think I have explained everything that needs to be evaluated.

Now I'm trying to understand the following things,

Question 1: Is there something SHOULD NOT be impelemented as I used?

Question 2:. What is the best approach to implementing limited contexts? I recently watched the videos of Julie Lerman and watched a lot of sample projects. I usually saw BC output from DbContext. But I could not be sure. Since I thought BC should be in a domain (business logic) not in a DbCore (data access) layer.

Question 3: As I mentioned above, my Api and Web projects use DTO, so both of them should have links to the domain level. But I didn’t like it, because I separate the business layer from the user interface API and bind them to objects again. But I could not find anything better than this.

This has become a long question, but I will be very happy if you share your ideas with me to create a better architecture.

+8
unit-of-work entity-framework-5 repository-pattern domain-driven-design bounded-contexts
source share
1 answer

Question 1 . Assuming you have a complex business domain and significant business logic, you can do everything possible because you need to isolate your domain level from infrastructure problems. However, this is often not the case. If you basically just move data from the database to the user interface and vice versa, then this is too complicated and you should look for something with fewer moving parts.

Question 2: How many separate domain models do you have (with different ubiquitous languages)? One? Two? Three? For each model, isolate it as much as possible from other models and infrastructure.

Eric Evans defines a limited context as primarily a linguistic boundary (quote from his book):

THE BOUNDED CONTEXT limits the applicability of a particular model , so that team members have a clear and common understanding of what to be consistent and how it relates to other CONTEXTS. Within this CONTEXT, work to ensure that the model is logically unified, but do not worry about applicability beyond these boundaries. In other CONTEXT, other models are used with differences in terminology, concepts and rules, and in dialects of UBIQUITOUS LANGUAGE.

DBContext may point you in the right direction, but remember that this is an infrastructure artifact, not a domain concept. It is a combination of Unit-Of-Work and Repository templates and allows you to query the database and group together the changes, which will then be written back to the repository as a unit. "_ (From MSDN Docs ).

DDD is domain modeling: using models to solve complex business problems in complex business areas. Deriving the boundaries of the model from technical considerations may feel like the tail wags the dog. Define the boundary of your model conceptually, then combine your technical infrastructure accordingly.

Question 3: DTO can be a good way to enforce a context boundary, for example for an API. The API can then function as an anti-corruption layer for other models. The reason people usually use them for user interfaces is to avoid having to introduce user interface concepts into the domain model.

Do not look for perfect architecture. And understand that “best practices” is really a guide based on specific situations. Follow the instructions that other more experienced people have laid out, realizing that your situation seems to be very different. Use what you have with the expectation of a reorganization of your design decisions when you discover friction. For example, if you later find that the DTOs for the user interface are full, then delete them. Simplify wherever you are.

+30
source share

All Articles