I'm working on a project in which my constructors contain - only - behavioral dependencies. i.e. I never pass values / state.
Example:
class ProductProcessor : IProductProcessor
{
public double SomeMethod(){ ... }
}
class PackageProcessor
{
private readonly IProductProcessor _productProcessor;
private double _taxRate;
public PackageProcessor(IProductProcessor productProcessor)
{
_productProcessor = productProcessor;
}
public Initialize(double taxRate)
{
_taxRate = taxRate;
return this;
}
public double ProcessPackage()
{
return _taxRate * _productProcessor.SomeMethod();
}
}
In order to pass state, it was decided to include a second step (a call to Initialize).
I know we can configure this as a named parameter in the IoC Container config class, however, we did not like the idea of creating "new namedParameter(paramvalue)'s" in the configuration file as it makes it unnecessarily unreadable and creates a future maintenance pain spot.
I've seen this pattern in more than one place.
Question: I read some consider this two step initialization an anti-pattern. If that is the consensus, wouldn't this imply a limitation / weakness of sorts in the approach of dependency injection via a IoC container?
Edit: After looking into Mark Seeman's suggestion:
and the answers to this one, I have a few comments: Initialize/Apply : Agree on it being an anti pattern / smell. Yacoub Massad: I agree IoC containers are a problem when it comes to primitive dependencies. Manual (poor man's) DI, as described here sounds great for smaller or architecturally stable systems but I think it could become very hard to maintain a number of manually configured composition roots.
Options: 1)Factories as dependencies (when run time resolution is required) 2) Separate stateful object from pure services as described here.
(1): This is what I had been doing but I realized that there is a potential to incur into a another anti-pattern: the service locator. (2): My preference for my particular case is this one about this one as I can cleanly separate both types. Pure services are a no brainer - IoC Container, whereas stateful object resolution will depend on whether they have primitive dependencies or not.
Every time I've 'had' to use dependency injection, it has been used in a dogmatic way, generally under the orders of a supervisor bent on applying DI with IoC container at any cost.