Monday, December 29, 2014

Abstract Factory Pattern

a common scenario where dependency injection is being used is that we end up passing multiple dependencies through the constructor of the dependent class and this sometimes causes the constructor to get bloated.
    public class Program
    {        
        ICustomerRepository _customerRepository;
        IItemRepository _itemRepository;

        public Program(ICustomerRepository customerRepository, IItemRepository itemRepository)
        {
            _customerRepository = customerRepository;
            _itemRepository = itemRepository;
        }

        public Customer GetCustomer()
        {
            return _customerRepository.Get(1);
        }

        public Item GetItem()
        {
            return _itemRepository.Get(123);
        }
    }

In the above code not all injected dependencies will be used equally and in the same manner, _customerRepository might be called more than _itemRepository which raises the question of why we instantiate them and inject them into a constructor using an IOC even though they are not needed immediately.

If we took a different approach and forced the repositories to implement a common interface like so:
    public interface IRepository
    {
        
    }

    public interface IRepository: IRepository where T : class, new()
    {
        T Add(T entity);
        T Update(T entity);
        T Remove(int id);
        T Get(int id);
    }

    
    public interface IRepositoryFactory
    {
        T GetRepository() where T : IRepository;
    }

we would be able to use an IOC such as structuremap to get an instance of Type T where T is IRepository and return it in our repository factory:

public class RepositoryFactory: IRepositoryFactory
{
    public T GetRepository() where T : IRepository
    {
       return ObjectFactory.GetInstance(T);
    }
}

now we can inject our Repository factory into our dependent class and use it to get our dependencies when they are needed:
    public class Program
    {
        IRepositoryFactory _repositoryFactory;

        public Program(IRepositoryFactory repositoryFactory)
        {
            _repositoryFactory = repositoryFactory;
        }

        public Customer GetCustomer()
        {
            var customerRepo = _repositoryFactory.GetRepository();
            return customerRepo.Get(1);
        }

        public Item GetItem()
        {
            var itemRepo = _repositoryFactory.GetRepository();
            return itemRepo.Get(1);
        }

        static void Main(string[] args)
        {
            BootStrapper.Execute();

            var p = new Program(ObjectFactory.GetInstance());         
        }
    }

No comments :

Post a Comment