I’m trying to exercise the principles of Dependency Injection, and I’m having some difficulty doing so.
I have a function that periodically goes off to my database, retrieves a list of products, and then runs a battery of tests against those products in order to determine their safety.
If one or more of the products is found to be unsafe, I need to issue a recall by instantiating and dispatching a ProductRecall object.
The function looks something like this: (pseudo-code)
void SafteyInspector::CheckProductSaftey()
{
database.getProducts( list_of_products )
foreach( list_of_products as p )
{
if ( !runBatteryOfTests( p ) )
unsafe_products.insert( p );
}
if ( !unsafe_products.empty() )
{
ProductRecall * recall =
new ProductRecall( unsafe_products ); // Oh no!
recall->dispatch();
}
}
The problem is that I’m “new”-ing a ProductRecall object right in the middle of my call-graph. This violates the principles of Dependency Injection. As written, I can’t test CheckProductSaftey() without also creating a ProductRecall object.
However, I can’t pass the ProductRecall object into my SafetyInspector object, because the SafetyInspector is the one who determines the list of unsafe products.
I’m using constructor-injection for everything, and I’d like to continue doing so. Note also that I may issue multiple ProductRecalls at any time, so I can’t necessarily just pass a single ProductRecall object into the SafetyInspector at construction.
Any suggestions? Thanks!
I think the problem may be with your implementation of
ProductRecall. Specifically, if you can calldispatch()on a newly created object, it implies that a lot of actual functionality is either hidden inside theProductRecallclass, or that theProductRecallclass has static members and/or singletons to give it everything else it needs.I would recommend creating a class called
ProductRecallDispatcherwhich handles the intricacies of an actual dispatch. You would then create one of these objects, and pass it to the constructor forSafteyInspector. This would make yourCheckProductSafetyfunction look as follows: