mercredi 22 juillet 2020

Unit of Work Pattern when repository has external dependencies

I am working on a relatively small application which architecture has a Repository pattern implemented in its DAL (Data Access Layer), encapsulating Entity Framework, as we may want to change ORM in the near future. I am now working on expanding this by implementing a Unit of Work pattern as well.

However an external dependency is being used to map the entity framework DTO's (generated when using a model first approach) to the domain objects. This means this dependency is being injected into the constructor of the repository service implementation, as such;

public class RepositoryService : IRepositoryService {

        private readonly IExternalDependency _mapper;
        private readonly DbContext _context;

        public RepositoryService(IExternalDependency mapper, DbContext context){
            _mapper = mapper;
            _context = context;
        }

        .
        .
        .
        public IEnumerable<DomainObjects> GetAllObjects();
        .
        . 
        . 

        etc
}

However, in the usual description of the Unit of Work pattern, the repositories are properties of the UnitOfWork class, which creates the problem of where to inject the mapper dependency.

public class UnitOfWork : IUnitOfWork {

    private readonly _dbContext { get; private set; }
    private RepositoryService _repository { get; private set;}

    public UnitOfWork(DbContextOptions options, IExternalDependency mapper)
    {
        _dbContext = new DbContext(options); 
        _repository = new RepositoryService(mapper, _dbContext); //Should we inject the mapper here?
    }
  
    public void RollBack()
    {
       ...
    }

    public int Commit()
    {
        return _dbContext .SaveChanges();
    }
}

How is this situation usually handled?

I think injecting it into the UnitOfWork class will lead to problems in the future because we lose most of the benefits of using it in the first place - we're tying ourselves to repositories that NEED a mapper injected into it, and the mapper instance will be shared among repositories (which we definitely don't want).

It also means upper layers will know about the mapper, which breaks encapsulation.

How would you go about this?

Aucun commentaire:

Enregistrer un commentaire