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
design
|dependency-injection
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
- DI all possible
IValidationService
andICustomerRepository
and switch based on type, which seems wrong. - The other is to change the service signature to
Save(IValidationService validation, ICustomerRepository repository, CustomerDTO customer)
which is an invasive change. 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