4

Our "unit of work" class has a method which takes a class type and creates a repository:

public IRepository<TEntity> GetRepository<TEntity>() where TEntity : class
        {
            var repoItem = _repositoryList.FirstOrDefault(cv => cv.GetType().IsGenericType && cv.GetType().GetGenericArguments()[0] == typeof(TEntity));
            if (repoItem == null)
            {
                repoItem = new Repository<TEntity, object>(Context);
                _repositoryList.Add(repoItem);
            }
            return repoItem as IRepository<TEntity>;
        }

For me, it looks very strange because the unit of work is not DI.

I tried to explain it to my team, but they always say "all examples of unit of work contain concrete classes, or properties/methods which can create and return repositories."

But my opinion about a "unit of work" is, it should know only what repositories exist, and when I call Savechanges, it should save the entities in all these repositories.

Now our services contructors takes only UnitOfWork, but my opinion is, it should take also the repository interfaces. Because UnitOfWork shouldn't be a God class which can do anything.

Do you have some good explanation why it is wrong\right?

5

The immediate problem I see here that it becomes hard to unit test the "UnitOfWork" with mock repositories. What if the line

    repoItem = new Repository<TEntity, object>(Context);

needs to be replaced by ... new MockRepository for a meaningful test?

So in case UnitOfWork just needs one or two, maybe 3 repos, you could try to inject them in the UnitOfWork constructor. If it needs more, but the repos can be instantiated beforehand, then you could also try to inject the filled _repositoryList beforehand, without extending it in UnitOfWork.

However, if your UnitOfWork is really so complex it requires to utilize lots of different repo classes, and creating the repos should be done only "on demand" (as shown in your example), then I would try the following: create a new class RepositoryFactory which encapsulates _repositoryList, refactor GetRepository to this new class, and inject an object of type IRepositoryFactory into the UnitOfWork. That gives you the necessary separation of reponsibilities, and will allow to inject a MockRepositoryFactory for a unit test.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.