Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency Injection, injecting an "injectable" object (service) into a newable (entity)

When writing code we should be able to identify two big group of objects:

  • Injectables
  • Newables

http://www.loosecouplings.com/2011/01/how-to-write-testable-code-overview.html

http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/

  • Injectable objects are objects (services) that expose dependencies in their constructors these dependencies are usually resolved using an IoC container, these objects can only ask for other injectables in their constructors

  • Newable are objects that also expose dependencies in their constructors but newables can only ask for other newable objects (Entities, Value Objects), another characteristic of newable objects is they should not hold a reference to an injectable object

But when writing code, we often need to "inject" a service (injectable) into an Entity (newable)

I have been thinking that maybe exposing a service dependency in a newable object is better doing it at method level but this sounds like a lot of work to do.... just thinking about resolving the dependencies every time a method is called.... well this smells like we would have to use the Service Locator anti-pattern

The way I have solved this is:

  • Create an interface with a method exposing the dependency (the service will be used in this method)

  • Create an Extension Method for the interface and place it in a different namespace, perhaps in another assembly, and just wrap the call to the original method resolving the dependency using a service locator

Doing this we have a consistent separation between newable and injectable objects with the ability to use services in our newables easily

  • What do you think?
  • Using the service locator in an extension method is considered a bad practice?
  • How would you unit-test the extension method call?
like image 489
Jupaol Avatar asked Mar 14 '12 11:03

Jupaol


1 Answers

But when writing code, we often need to "inject" a service (injectable) into an Entity (newable)

This is not the case- if you find the need to do this then there is some functionality that exists in the Entity which should be in a service.

Let's say your newable is ShoppingCart and your injectable is a database repository. You want to be able to do this:

// somehow cart already got the repository
cart.save();

Well, you're doing it wrong. Instead you need to switch things around and do:

respository.save( cart );

If you could provide an situation of when you feel the need to do this, we could discuss specifics of that situation.

like image 127
WW. Avatar answered Sep 20 '22 13:09

WW.