Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an alternative to bastard injection? (AKA poor man's injection via default constructor)

People also ask

What is the alternative to dependency injection?

An alternative to dependency injection is using a service locator. The service locator design pattern also improves decoupling of classes from concrete dependencies. You create a class known as the service locator that creates and stores dependencies and then provides those dependencies on demand.

What is poor man's dependency injection?

Dependency injection is basically the process of providing the objects that an object needs (its dependencies) instead of having it construct them itself. It's a very useful technique for testing. You don't need any framework to have dependency injection.

Which is best dependency injection?

Constructor ControllerConstructor-based dependency injection is certainly considered a best practice. There was a time I personally favored setter-based injection, but I have come around to constructor-based. We can still improve our example.


As far as I understand, this question relates to how to expose a loosely coupled API with some appropriate defaults. In this case, you may have a good Local Default, in which case the dependency can be regarded as optional. One way to deal with optional dependencies is to use Property Injection instead of Constructor Injection - in fact, this is sort of the poster scenario for Property Injection.

However, the real danger of Bastard Injection is when the default is a Foreign Default, because that would mean that the default constructor drags along an undesirable coupling to the assembly implementing the default. As I understand this question, however, the intended default would originate in the same assembly, in which case I don't see any particular danger.

In any case you might also consider a Facade as described in one of my earlier answers: Dependency Inject (DI) "friendly" library

BTW, the terminology used here is based on the pattern language from my book.


My trade-off is a spin on @BrokenGlass:

1) Sole constructor is parameterized constructor

2) Use factory method to create a ThingMaker and pass in that default source.

public class ThingMaker {
  public ThingMaker(IThingSource source){
    _source = source;
  }

  public static ThingMaker CreateDefault() {
    return new ThingMaker(new DefaultThingSource());
  }
}

Obviously this doesn't eliminate your dependency, but it does make it clearer to me that this object has dependencies that a caller can deep dive into if they care to. You can make that factory method even more explicit if you like (CreateThingMakerWithDefaultThingSource) if that helps with understanding. I prefer this to overriding the IThingSource factory method since it continues to favor composition. You can also add a new factory method when the DefaultThingSource is obsoleted and have a clear way to find all the code using the DefaultThingSource and mark it to be upgraded.

You covered the possibilities in your question. Factory class elsewhere for convenience or some convenience within the class itself. The only other unattractive option would be reflection-based, hiding the dependency even further.


One alternative is to have a factory method CreateThingSource() in your ThingMaker class that creates the dependency for you.

For testing or if you do need another type of IThingSource you would then have to create a subclass of ThingMaker and override CreateThingSource() to return the concrete type you want. Obviously this approach only is worth it if you mainly need to be able to inject the dependency in for testing, but for most/all other purposes do not need another IThingSource


I vote for #3. You'll be making your life--and the lives of other developers--easier.


If you have to have a "default" dependency, also known as Poor Man’s Dependency Injection, then you have to initialize and "wire" the dependency somewhere.

I will keep the two constructors but have a factory just for the initialization.

public class ThingMaker
{
    private IThingSource _source;

    public ThingMaker(IThingSource source)
    {
        _source = source;
    }

    public ThingMaker() : this(ThingFactory.Current.CreateThingSource())
    {
    }
}

Now in the factory create the default instance and allow the method to be overrided:

public class ThingFactory
{
    public virtual IThingSource CreateThingSource()
    {
        return new DefaultThingSource();
    }
}

Update:

Why using two constructors: Two constructors clearly show how the class is intended to be used. The parameter-less constructor states: just create an instance and the class will perform all of it's responsibilities. Now the second constructor states that the class depends of IThingSource and provides a way of using an implementation different than the default one.

Why using a factory: 1- Discipline: Creating new instances shouldn't be part of the responsibilities of this class, a factory class is more appropriate. 2- DRY: Imagine that in the same API other classes also depend on IThingSource and do the same. Override once the factory method returning IThingSource and all the classes in your API automatically start using the new instance.

I don't see a problem in coupling ThingMaker to a default implementation of IThingSource as long as this implementation makes sense to the API as a whole and also you provide ways to override this dependency for testing and extension purposes.


You are unhappy with the OO impurity of this dependency, but you don't really say what trouble it ultimately causes.

  • Is ThingMaker using DefaultThingSource in any way that does not conform to IThingSource? No.
  • Could there come a time where you would be forced to retire the parameterless constructor? Since you are able to provide a default implementation at this time, unlikely.

I think the biggest problem here is the choice of name, not whether to use the technique.


The examples usually related to this style of injection are often extremely simplisitic: "in the default constructor for class B, call an overloaded constructor with new A() and be on your way!"

The reality is that dependencies are often extremely complex to construct. For example, what if B needs a non-class dependency like a database connection or application setting? You then tie class B to the System.Configuration namespace, increasing its complexity and coupling while lowering its coherence, all to encode details which could simply be externalized by omitting the default constructor.

This style of injection communicates to the reader that you have recognized the benefits of decoupled design but are unwilling to commit to it. We all know that when someone sees that juicy, easy, low-friction default constructor, they are going to call it no matter how rigid it makes their program from that point on. They can't understand the structure of their program without reading the source code for that default constructor, which isn't an option when you just distribute the assemblies. You can document the conventions of connection string name and app settings key, but at that point the code doesn't stand on its own and you put the onus on the developer to hunt down the right incantation.

Optimizing code so those who write it can get by without understanding what they are saying is a siren song, an anti-pattern that ultimately leads to more time lost in unraveling the magic than time saved in initial effort. Either decouple or don't; keeping a foot in each pattern diminishes the focus of both.