Constructor Injection vs Setter Injection

Constructor injection is theoretically superior:

Constructor Injection vs Setter Injection
Constructor vs Setter Injection – Constructor is Better
Setter injection versus constructor injection and the use of required

Before I built RobotLegs I was sold on constructor injection. My prototype, however, used SmartyPants-IOC which lacked constructor injection, so I bit my lip and used setter injection. In practice I found that often, especially with framework actors, it was incredibly convenient.

Effort

Unless you use a code generator, constructor injection requires roughly 3 times the effort (more code) and is roughly 3 times more prone to human error than this form of setter injection:

public class SomeMediator
{
  [Inject] public var someView:SomeView;
  [Inject] public var someProxy:SomeProxy;
  [Inject] public var someService:ISomeService;

  public function SomeMediator()
  {
  }
}

Constructor injection requires twice the number of declarations and an extra assignment step.

public class SomeMediator
{
  private var someView:SomeView;
  private var someProxy:SomeProxy;
  private var someService:ISomeService;

  public function SomeMediator( someView:SomeView, someProxy:SomeProxy, someService:ISomeService )
  {
    // Boilerplate...
    this.someView = someView;
    this.someProxy = someProxy;
    this.someService = someService;
  }
}

Forgetfulness

Let’s consider what Misko deems the biggest problem with setter injection: forgetting dependencies.

In the case of setter injection, and in the context of the application itself (running on the RobotLegs framework), if we forget to set up a dependency rule, we’ll get a runtime error when the DI framework tries to inject into the Mediator (which happens automatically). This would be exactly the same for Constructor injection. A draw.

If we are instantiating the Mediator manually (in a unit test for example), and we don’t manually inject into it with our DI framework, then setter injection is obviously weaker – we won’t get the DI RTE, we’ll just get a null-pointer exception at some point in our test. Constructor injection is much better here, but something Misko overlooks is that constructor injection is more prone to human error from the inside. We have at least three places where we can forget to properly take care of our dependencies:

  1. We might declare the dependency in our constructor argument list, but then forget to store the passed value inside our constructor.
  2. We might declare a property on the class itself but then forget to ask for it in the ctor argument list.
  3. We might even be so delirious as to incorrectly assign the values in our ctor by excluding “this.”.

None of those mistakes will cause a compile-time error. As with setter injection, we’ll just get a RTE at some point. Again, a draw.

When we consider what a Mediator is, and the fact that Mediators are amongst the biggest candidates for re-factoring (we might start with one Mediator for a complex nested view, for example, and then break it out into several finely grained Mediators later), setter injection becomes even more convenient. Constructor injection requires more effort when dependencies change: 3 places need editing, including the constructor’s method signature – necessitating external changes for any manually instantiated instances.

Inconsistent State

Another charge against setter injection is that it can be responsible for objects in inconsistent states: directly after construction, and before injection has occurred, the object is not quite ready for use (it’s dependencies are missing). But this isn’t much of a problem when your architectural framework handles that side of things automatically – it instantiates and injects things for you.

Hybrids In Progress, A Sliding Scale

I’d also like to touch on the mixing of injection styles. Some people see this as akin to mixing coding standards in a project – ugly. At the same time, setter injection must be used under certain conditions (circular dependencies for example), so even purists have to mix styles sometimes. I’ve chosen to roll with it, and use what makes the most sense for the case at hand. Looking at actors in the RobotLegs framework, I’m inclined towards:

  • Setter injection for Mediators
  • Setter injection for Commands
  • Constructor injection for Proxies
  • Constructor injection for Services
  • Constructor injection for non-framework entities

My reasoning is that:

  • Mediators and Commands generally have more dependencies and require refactoring more frequently
  • Proxies and Services should have very few dependencies
  • Non-framework entities are more likely to be created manually

If we look at setter vs ctor injection on a sliding scale, we have:

  • setter -> constructor
  • convenient -> safe

We can always migrate from setter to ctor injection as classes settle down and their refactoring likelihood decreases:

  • setter -> constructor
  • sketchy -> final

Mediators, by their very nature, are the sketchiest parts of an application: they are tightly coupled both to the application and the view. Commands are coupled to the application. There is very little need to make either of these actors “safe” or “final”, and for flexibility it is wise to leave them “convenient”.

Proxies and Services, however, should not be too coupled to the application. They should be the “safest” most “final” classes in the interests of loose coupling and portability. I would start with setter injection and migrate to constructor injection as those components mature.

Prompted By:

This comment, thanks!

Posted in Banter, Robotlegs | Tagged , , , , , , , | 12 Comments
  • Darren

    Great post Shaun. It highlights well some issues that often aren’t discussed when comparing the two types of injection. One issue that you don’t mention though is the order of instantiation of properties. If having some control over the order of instantiation of properties is important to your class, I think constructor injection has an advantage in this regard. Of course, there’s ways to achieve this with setter injection but I don’t think they are nearly as clean. This can make mixing injection types messy – what do you do if you have just one or two classes of the *types* of classes that you have chosen to use setter injection where order of instantiation of properties is important ?

    I haven’t had a chance to try Smartypants-IOC yet but it looks like properties which should really be private are made public to satisfty the injection framework. Is this the case or does the Inject metadata do some magic that I’m not aware of?

  • Darren

    Great post Shaun. It highlights well some issues that often aren’t discussed when comparing the two types of injection. One issue that you don’t mention though is the order of instantiation of properties. If having some control over the order of instantiation of properties is important to your class, I think constructor injection has an advantage in this regard. Of course, there’s ways to achieve this with setter injection but I don’t think they are nearly as clean. This can make mixing injection types messy – what do you do if you have just one or two classes of the *types* of classes that you have chosen to use setter injection where order of instantiation of properties is important ?

    I haven’t had a chance to try Smartypants-IOC yet but it looks like properties which should really be private are made public to satisfty the injection framework. Is this the case or does the Inject metadata do some magic that I’m not aware of?

  • http://shaun.boyblack.co.za/blog/ shaun

    Thanks Darren. Doh, I totally forgot about the “ordering” issue – probably because I haven’t come across it in my own code (yet), but also perhaps because I have a feeling it may be invalid..

    Should the order in which we are given our dependencies ever be important?

    I don’t think so. What’s important is that our dependencies be entirely satisfied at some point, and that we know when that point is: so that we can consider ourselves “fully” constructed or “ready” and get on with things.

    The order of instantiation of the dependencies themselves might be important, but that is not our concern – that is the concern of the container. That’s context stuff, and shouldn’t matter to us inside our class where we have a specific job to do.. when we’re “ready”.

    And how do we know when we’re ready? Well, that’s the murky part.. “When we’re told so”.

    I might well be overlooking something, but I hope not.

    As for the SmartPants-IOC setter vibes.. yes,.. “properties which should really be private are made public to satisfy the injection framework”. Yeh, I know what you’re thinking!.. But is that really so bad when one views dependencies as immutable properties? – set during the construction phase, and never altered thereafter.

    Manipulating objects (changing their state) from the outside isn’t such a good idea most of the time anyway – it puts knowledge in the wrong place and is often responsible for tight coupling. Properties don’t make for good API’s. Here, properties are bad.

    On the other side of the fence live Value Objects. No logic, no methods, no access control, just complex, nested, value types.. value structures. Public properties. Here, properties are good.

    To help me sleep better, I just lump dependencies in the same conceptual bucket as Value Objects.. and hope that the nagging feeling fades over time!

  • http://www.boyblack.co.za shaun

    Thanks Darren. Doh, I totally forgot about the “ordering” issue – probably because I haven’t come across it in my own code (yet), but also perhaps because I have a feeling it may be invalid..

    Should the order in which we are given our dependencies ever be important?

    I don’t think so. What’s important is that our dependencies be entirely satisfied at some point, and that we know when that point is: so that we can consider ourselves “fully” constructed or “ready” and get on with things.

    The order of instantiation of the dependencies themselves might be important, but that is not our concern – that is the concern of the container. That’s context stuff, and shouldn’t matter to us inside our class where we have a specific job to do.. when we’re “ready”.

    And how do we know when we’re ready? Well, that’s the murky part.. “When we’re told so”.

    I might well be overlooking something, but I hope not.

    As for the SmartPants-IOC setter vibes.. yes,.. “properties which should really be private are made public to satisfy the injection framework”. Yeh, I know what you’re thinking!.. But is that really so bad when one views dependencies as immutable properties? – set during the construction phase, and never altered thereafter.

    Manipulating objects (changing their state) from the outside isn’t such a good idea most of the time anyway – it puts knowledge in the wrong place and is often responsible for tight coupling. Properties don’t make for good API’s. Here, properties are bad.

    On the other side of the fence live Value Objects. No logic, no methods, no access control, just complex, nested, value types.. value structures. Public properties. Here, properties are good.

    To help me sleep better, I just lump dependencies in the same conceptual bucket as Value Objects.. and hope that the nagging feeling fades over time!

  • http://www.bigroom.co.uk/ Richard Lord

    Hi Shaun

    One area where constructor injection becomes very useful is with existing code. If classes require their dependencies in the constructor there is no need for language constructs like smarty-pants’ [Inject] meta-data in order to enable the injection. This makes it easier to use existing code libraries with a DI container if the container uses constructor injection.

    On the other hand, due to the method of their construction, it’s difficult to use constructor injection with Flex components.

    Because MXML pushes us towards constructors with no parameters, I’m inclined towards setter injection for Flex projects. But it does frustrate when one wants to use DI with an existing open source library like Away3D or my own Flint.

  • http://www.bigroom.co.uk/ Richard Lord

    Hi Shaun

    One area where constructor injection becomes very useful is with existing code. If classes require their dependencies in the constructor there is no need for language constructs like smarty-pants’ [Inject] meta-data in order to enable the injection. This makes it easier to use existing code libraries with a DI container if the container uses constructor injection.

    On the other hand, due to the method of their construction, it’s difficult to use constructor injection with Flex components.

    Because MXML pushes us towards constructors with no parameters, I’m inclined towards setter injection for Flex projects. But it does frustrate when one wants to use DI with an existing open source library like Away3D or my own Flint.

  • http://shaun.boyblack.co.za/blog/ shaun

    Hi Richard,

    I fully agree! I should point out that most of my thinking has been in the realm of architectural/application framework design (see: RobotLegs).

    I’m hoping that SmartyPants-IOC introduces constructor injection soon (it has been rumoured). Well, actually I’m hoping that someone releases a DI framework with no Flex dependencies that supports both constructor and annotated setter injection :)

    For my framework actors (modelled on PureMVC) I’m happy with annotated setter injection – as the actors are mostly just hookup/decoupling/bridge points and tend to change quite a bit as an application grows. Once an application’s architectural design has settled down, however, I would like to be able to refactor to constructor injection.

  • http://www.boyblack.co.za shaun

    Hi Richard,

    I fully agree! I should point out that most of my thinking has been in the realm of architectural/application framework design (see: RobotLegs).

    I’m hoping that SmartyPants-IOC introduces constructor injection soon (it has been rumoured). Well, actually I’m hoping that someone releases a DI framework with no Flex dependencies that supports both constructor and annotated setter injection :)

    For my framework actors (modelled on PureMVC) I’m happy with annotated setter injection – as the actors are mostly just hookup/decoupling/bridge points and tend to change quite a bit as an application grows. Once an application’s architectural design has settled down, however, I would like to be able to refactor to constructor injection.

  • srikanth

    what ever you stated is true but requested to have a look on Context IOC, And i hope its all up to the developer which on to choose, if we keep OOP’s in mind

  • srikanth

    what ever you stated is true but requested to have a look on Context IOC, And i hope its all up to the developer which on to choose, if we keep OOP’s in mind

  • http://twitter.com/mcksembwever Michael Semb Wever

    Great read!

    Just wrote an article that questions the preference towards constructor injection by investigating IoC (like you have also done here), API Design, and other factors in the big picture of coding the application.
     http://tech.finn.no/2011/05/13/dependency-injection-with-constructors/

  • Pingback: Dependency Injection with constructors? « FINN.no tech blog