# 1. Implementing Repository Pattern ## Branching - [ ] Create the feature/repositories branch based on develop ## Create `IRepository` in Domain - [ ] Create the interface and add the following code 📂 Suggested Folder: `Domain/Framework/Interfaces/Respositories` ```c# public interface IRepository where T_Entity : class { Task GetByIdAsync(U_PrimaryKey id); Task> GetAllAsync(); Task> FindAsync(Expression> predicate); Task AddAsync(T_Entity entity); void Update(T_Entity entity); void Remove(T_Entity entity); } ``` ## Create a class implementing `IRepository` - [ ] create a class named `BaseRepository` or `Repository` (choose one) in Infrastructure and implement `IRepository` 📂 Suggested Folder: `Infrastructure/Framework/Base` - [ ] provide method definitions for the methods ```c# public class BaseRepository : IRepository where T_Entity : class where K_DbContext : DbContext { public virtual K_DbContext DbContext { get; set; } public virtual DbSet DBSet{ get; set; } public BaseRepository(K_DbContext dbContext) { DbContext = dbContext; DBSet = dbContext.Set(); } public async Task AddAsync(T_Entity entity) { await DBSet.AddAsync(entity); } public async Task GetByIdAsync(U_PrimaryKey id) { return await DBSet.FindAsync(id); } public async Task> GetAllAsync() { var entityList = DBSet.ToListAsync(); return await entityList; } public void Update(T_Entity entity) { DBSet.Update(entity); } public void Remove(T_Entity entity) { DBSet.Remove(entity); } public async Task> FindAsync(Expression> predicate) { return await DBSet.Where(predicate).ToListAsync(); } } ``` ## Create one interface for each entity(except the join tables for now), and name it `I[Entity]Repository` - [ ] For each entity, create an interface that inherits `IRepository` - [ ] (Optional): Add method definitions as you deem needed for that entity (not recommended right now. We will come back to this part later) 📂 Suggested Folder: Domain/Framework/Base/Interfaces/{Related Folder}` for example: ```c# public interface IAccountRepository : IRepository { } ``` ### Reference Project: https://github.com/MehrdadShirvani/AlibabaClone-Backend/tree/develop/AlibabaClone.Domain/Framework/Interfaces/Repositories ## Create one class for each entity, implementing the `I[Entity]Repository` 📂 Suggested Folder: Infrastructure/Services/{Related Folder} - [ ] For each entity, create an class named `[Entity]Repository` that implements `I[Entity]Repository` and inherits `BaseRepository` for example: ```c# public class AccountRepository : BaseRepository, IAccountRepository { public AccountRepository(ApplicationDBContext dbContext) : base(dbContext) { } } ``` ### Reference Project: https://github.com/MehrdadShirvani/AlibabaClone-Backend/tree/develop/AlibabaClone.Infrastructure/Services ## Registering Services - [ ] Modify `Program.cs` in Presentation, and register for each `I[Entity]Repository` the related `[Entity]Repository` ```c# //some code //Register Repositories builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); //some code ``` ## Merge - [ ] Create a PR and merge the current branch with develop # 2. Implementing Unit of Work Pattern ## Branching - [ ] Create the feature/UnitOfWork branch based on develop ```c# public interface IUnitOfWork : IDisposable { Task SaveChangesAsync(); } ``` ## Create `IUnitOfWork` in Domain - [ ] Create the interface that inherits `IDisposable` and add the following code 📂 Suggested Folder: `Domain/Framework/Interfaces` ```c# public interface IUnitOfWork : IDisposable { Task SaveChangesAsync(); } ``` ## Create a class implementing `IUnitOfWork` - [ ] create a class named `UnitOfWork` in Infrastructure and implement `IUnitOfWork` 📂 Suggested Folder: `Infrastructure/Framework/Base` - [ ] provide method definitions for the methods ```c# public class UnitOfWork : IUnitOfWork { private readonly ApplicationDBContext _context; public UnitOfWork(ApplicationDBContext context) { _context = context; } public void Dispose() { _context.Dispose(); } public async Task SaveChangesAsync() { return await _context.SaveChangesAsync(); } } ``` ## Registering Services - [ ] Modify `Program.cs` in Presentation, and register the `UnitOfWork` Service ```c# //some code //Register Repositories builder.Services.AddScoped(); //some code ``` ## Merge - [ ] Create a PR and merge the current branch with develop