The generic pattern allows us to use the same method for a different set of entities. However, it also creates a problem that related entities are partially updated which will lead to an error not to mention that we have to inject each entity separately.
To solve this problem, we will see another pattern called the unit of work.
List of Contents
Setting Up a Project
Creating a WepAPI
How to create .NET web-API
Setting up development tools When working with .NET, we need tools to create a web application. We can download them at the link below. .NET | Free. Cross-platform. Open Source. (microsoft.com) .NET | Free. Cross-platform. Open Source. .NET is a developer
jin-co.tistory.com
Setting Up the Generic Pattern
Application Architecture - Generic Repository
The repository pattern has a static type so whenever we create an entity, we have to create a repository as well. A generic is a way to restrict to a type or to dynamically change types. Let's see how we can use a generic repository for multiple entities P
jin-co.tistory.com
Implementation
Adding a Work Unit Interface
Create a class file to use as an interface
Inherit from the 'IDisposable' interface (This interface makes sure components are disposed of after use). Then add an array to store the status of each entity.
Implementing the Work Unit Interface
Create another class to implement the interface
Add a constructor and inject the context. Add a private hash table field to manage the status of repositories.
private readonly StoreContext _context;
private Hashtable _repos;
public WorkUnit(StoreContext context)
{
this._context = context;
}
Update the implemented method with the code shown below.
public async Task<int> Completed()
{
return await _context.SaveChangesAsync();
}
public void Dispose()
{
_context.Dispose();
}
public IGenericRepo<T> Repo<T>() where T : BaseEntity
{
if (_repos == null) _repos = new Hashtable();
var type = typeof(T).Name;
if (!_repos.ContainsKey(type))
{
var repoType = typeof(GenericRepo<>);
var repoInstance = Activator.CreateInstance(repoType.MakeGenericType(typeof(T)), _context)
_repos.Add(type, repoInstance);
}
return (IGenericRepo<T>)_repos[type];
}
Registering the Work Unit Interface
Go to the Program.cs file and add the interface as a service.
builder.Services.AddScoped<IWorkUnit, WorkUnit>();
Adding Methods to Manage Entities' Status
Go to the generic interface and add methods to manage the status of entities.
void Add(T entity);
void Update(T entity);
void Delete(T entity);
Move to the implementing class and update the implementation. Update the methods with the code shown below. Basically, the Add method will add entities but not save changes until we call the Complete
public void Add(T entity)
{
_context.Set<T>().Add(entity);
}
public void Delete(T entity)
{
_context.Set<T>().Remove(entity);
}
public void Update(T entity)
{
_context.Set<T>().Attach(entity);
_context.Entry(entity).State = EntityState.Modified;
}
Updating the Controller
Go to the controller file
Delete the generic injection for each entity and inject the unit of the work interface.
Updating Data in the Database
As I mentioned above we do not update the data until we are done and call the Complete method. So if there is an error in updating one of the entities the data won't be updated at all in its entity
We have seen how we can update the generic pattern with the unit of work pattern. The unit of work pattern fills a hole in the generic pattern by linking entities to a unit that works in a linear manner without sacrificing the type flexibility of the generic pattern.
'Backend > .NET' 카테고리의 다른 글
Working with Postgres - Code First (0) | 2023.05.23 |
---|---|
.NET, Angular Deployment - Linux (0) | 2023.05.23 |
Server Memory - Redis (3) | 2023.05.10 |
Project Structure and Optimizing Development Environment (0) | 2023.05.07 |
Packages - Identity (0) | 2023.05.01 |