Search code examples
c#dependency-injectionrepository-patternunit-of-work

Injecting repository dependencies into a Unit of Work


I'm trying to employ the Repository and Unit of Work patterns in my asp.net MVC project, however I'm having difficulty figuring out how to pass Repository dependencies to the Unit of Work. The general standard structure of the Unit of Work seems to be the following:

public class UnitOfWork : IUnitOfWork
 {
        private ICustomerRepository _customerRepository;

        public ICustomerRepository CustomerRepository
        {
            get
            {
                if (this._customerRepository == null)
                {
                    this._customerRepository = new CustomerRepository(someContext);
                }
                return _customerRepository;
            }
        }
}

Specifically, what's confusing me is this line:

this._customerRepository = new CustomerRepository(someContext);

By defining interfaces for repositories, isn't the whole idea about being able to inject Repository dependencies into the UoW as time progresses and business needs change? If so, why does almost every implementation I see online do the above? In this implementation how are we supposed to pass a new instance of ICustomerRepository to the UoW? Surely we would need to also change code in the UoW and isn't that against the open close principle? How would I inject repositories to my UoW?

I've look around SO, and this question seems to have been asked before, but I'm still having a hard time trying to understand the proposed solution (a facade service).


Solution

  • There are two common ways to get an instance of your CustomerRepository. First approach is known as constructor injection which is a simple parameter in your constructur e.g.

    public class UnitOfWork : IUnitOfWork
    {
        public UnitOfWork(ICustomerRepository repository)
        {
            _customerRepository = repository;
        }
    
        private ICustomerRepository _customerRepository;
    
        public ICustomerRepository CustomerRepository
        {
            get
            {
                if (this._customerRepository == null)
                {
                    throw new ArgumentException("Missing repository");
                }
                return _customerRepository;
            }
        }
    }
    

    The second and more flexible way is to use an IoC Framework like Structuremap, Unity, Ninject... and so on.

    Here's an example of Structuremap:

    public class UnitOfWork : IUnitOfWork
    {
        private ICustomerRepository _customerRepository;
    
        public ICustomerRepository CustomerRepository
        {
            get
            {
                if (this._customerRepository == null)
                {
                    _customerRepository = ObjectFactory.GetInstance<ICustomerRepository>();
                }
                return _customerRepository;
            }
        }
    }
    

    Additionaly you need a configuraiton class to tell Structuremap which class to instantiate which could simply look like this:

    public static class RepositoryRegistry
    {
        internal static void DefaultConfiguration(Registry registry)
        {
           registry.For<ICustomerRepository>().Use<CustomerRepository>();
        }
    }