How to do dependency Injection and conditional object creation based on type?

Posted by Pradeep on Programmers See other posts from Programmers or by Pradeep
Published on 2012-11-19T13:52:29Z Indexed on 2012/11/19 17:20 UTC
Read the original article Hit count: 307

I have a service endpoint initialized using DI. It is of the following style. This end point is used across the app.

 public class CustomerService : ICustomerService
{
    private IValidationService ValidationService { get; set; }
    private ICustomerRepository Repository { get; set; }

    public CustomerService(IValidationService validationService,ICustomerRepository repository)
    {
        ValidationService = validationService;
        Repository = repository;
    }


    public void Save(CustomerDTO customer)
    {
        if (ValidationService.Valid(customer))
            Repository.Save(customer);
    }

Now, With the changing requirements, there are going to be different types of customers (Legacy/Regular). The requirement is based on the type of the customer I have to validate and persist the customer in a different way (e.g. if Legacy customer persist to LegacyRepository).

The wrong way to do this will be to break DI and do somthing like

  public void Save(CustomerDTO customer)
    {
        if(customer.Type == CustomerTypes.Legacy)
        {
            if (LegacyValidationService.Valid(customer))
                LegacyRepository.Save(customer);
        }
        else
        {
            if (ValidationService.Valid(customer))
                Repository.Save(customer);
        }
    }

My options to me seems like

  1. DI all possible IValidationService and ICustomerRepository and switch based on type, which seems wrong.
  2. The other is to change the service signature to Save(IValidationService validation, ICustomerRepository repository, CustomerDTO customer) which is an invasive change.
  3. Break DI. Use the Strategy pattern approach for each type and do something like:

    validation= CustomerValidationServiceFactory.GetStratedgy(customer.Type);
    validation.Valid(customer)
    

    but now I have a static method which needs to know how to initialize different services.

I am sure this is a very common problem, What is the right way to solve this without changing service signatures or breaking DI?

© Programmers or respective owner

Related posts about design

Related posts about dependency-injection