Skip to end of metadata
Go to start of metadata

Symptoms

Classes that depend on the container.

Consider the following example. We have a class BImpl that requires an A instance. It declares the dependency on the container so it can look up that A:

It can be used in the following way:

This will work, but it's an antipattern.

The reasons why the above implementation of BImpl is an antipattern are:

  • It introduces an unneeded dependency from BImpl to the container.
  • This makes BImpl hard to test without a container.
  • B assumes that the container has a registered an A. As a result, B won't FailFast if it hasn't. Instead, a will reference null, and BImpl will FailLate.

Causes

Not sure. Poor understanding of how PicoContainer works? Not being able to think "simple"?

What to do

The simple and elegant solution to this antipattern is not to complicate the world more than it is.
Here is how it should be:

PicoContainer will figure out that BImpl needs an A instance, and will pass in the AImpl, as this is an implementation of A.

Labels
  • None
  1. Apr 01, 2005

    While I agree with this antipattern, I'd like the following question to be answered. Assume that you have not a trivial example like here but a real project. Hierarchy of component might be quite big. Let's say you have a component 20 level deep relative to root component. This root component was instantiated by some bootstrap class that configured PicoContainer properly.
    Now what if my nested component needs additional dependency, that is addition constructor parameter new to the project? If I will try to avoid antipattern I will need to propagate this parameter from to bottom to the top. And this might be quite frustrating at top-level component to see constructor parameters that neither this class nor classes it immediately depend on ever need.
    My guess that some kind of Service Locator (PicoContainer might be considered as one) could be quite useful as it is much easier to pass one parameter to class constructor instead of passing tens of them and propagate or delete them from class hierarchy as nested components change. But this is kind of against whole dependency injection philosophy where you get only what you need...

  2. Apr 01, 2005

    If some class needs to be modified to accomodate for an additional dependency, you just declare another constructor parameter in that class.

    As long as you have registered all classes your system requires in your PicoContainer, all dependencies will be injected by PicoContainer.

    I don't understand what you mean by propagating parameters from the bottom to the top.

    I'm not sure I understand your problem. Perhaps you could illustrate with some code? Feel free to ask on the mailing list too.

  3. Jan 25, 2011

    Hello, fellow developers!
    The topic seems quite old, nevertheless, i'll try asking my stupid question.
    The antipattern on this page is quite clear (even to me). But, i ran into an 2 issues that's been haunting me for a couple of days.
    They seem to originate from 1 thing that can be described as "conditional injection", "partial injection" or "pulling dependencies".
    The main idea is that until an instance of a class runs a method of its own, it really can't figure out the components it needs to work properly.
    (sorry, i don't speak Java; i'll use AS3 although underneath it all is PHP)

    So, it's like the component needs to "pull necessaries" (or inform the injector that it is ready to receive an injection) at some point during method execution, because either:

    • the number of necessaries is too large
    • the necessaries are rather heavy (and we want performance)
    • the necessaries are unknown until runtime (although this in a way contradicts the principle that a "component should only implement 1 function but do it well")

    i'd really appreciate some feedback and pointers where my mind went really wrong ...
    thanks!

    Vasi