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.