16

I see lead developers writing code like this and upon reading Mark Seemann's book "Dependency Injection in .NET" I'm wondering if the specific "new" is "foreign", thus "Bastard Injection"??

public class SessionInitServiceManager
{
    protected readonly ICESTraceManager _traceManager;
    protected readonly ILogger _logger;
    protected readonly IAggregateCalls _aggregator;
    protected readonly IMultiCoreRepository _repository;

    public SessionInitServiceManager(ICESTraceManager traceManager,
                                     ILogger logger,
                                     IAggregateCalls aggregator,
                                     IMultiCoreRepository repository)
    {
        _traceManager = traceManager;
        _logger = logger;
        _aggregator = aggregator;
        _repository = repository;
    }

    public SessionInitServiceManager() : this(new CESTraceManager(),
                                              new Logger("BusinessServices.authenticateUser"),
                                              new Aggregator(),
                                              new RepositoryFactory().BuildMultiCoreRepository()) { }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tom Stickel
  • 19,633
  • 6
  • 111
  • 113
  • As an aside, four parameters is pushing the limit of sensible DI (the author states that his limit is generally four) because it forces you to start questioning whether SessionInitServiceManager is violating SRP. Passing in another manager class also suggests this may be the case. – RichK Dec 06 '11 at 00:15
  • Yes, I recall reading that 3-4 is general limit. Any good examples of how to avoid this newing issue with or without a IOC container like unity. ? – Tom Stickel Dec 06 '11 at 00:19
  • 4
    The answer depends on whether or not any of the 'default' implementations are defined within the same library or in a different library. http://stackoverflow.com/questions/6733667/is-there-an-alternative-to-bastard-injection-aka-poor-mans-injection-via-defa/6739953#6739953 – Mark Seemann Dec 06 '11 at 07:01
  • @MarkSeemann Ok, that clears things up for me. Thanks Mark! I'm enjoying your book BTW. Thanks! – Tom Stickel Dec 06 '11 at 07:31

2 Answers2

7

This for sure looks like a classic example of Bastard Injection. The reason why is because you have what appears as four Foreign Defaults. Foreign Default refers to a default value in which the type comes from a different module/project/DLL. I would propyl include namespace into that definition, because name spaces can signify boundaries in which at a future point you make breakout into its own module. This is more of being mindful about that when you decide to use a local default (Would I split this into its own module in the future?).

The way this wouldn’t be Bastard Injection would be that all these classes live within the same module. The thing that makes this so bad is because you drag the dependencies along, and now your class is tightly coupled to these classes. If I choose to use my own version of logging I have to take along the DLL for logging and so on, even though I don’t use, negating the benefits of modular application design.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
LCarter
  • 473
  • 7
  • 13
0

I happened to have borrowed that book, dependency injection in .NET, from a friend. I see what you are saying. I do believe that this is "bastard injection". It is a brutal term, but I suppose fitting after all ColdFusion (cough) has a "CFABORT" tag as part of the language.

Also, I noticed a good article, blog post How not to do dependency injection - the static or singleton container.

Basically, before we begin, let's get something out of the way:

Dependency Injection != Using an IoC container"

Here is the kicker, "This is the birth of the static container. Instead of changing the constructor of the controller to take in the dependency, we are just changing the line where the service is instantiated to resolve it using the container instead."

 public class HomeController
 {
    private readonly IExampleService _service;

    public HomeController()
    {
      _service = Container.Instance.Resolve<IExampleService>();
    }

    public ActionResult Index()
    {
      return View(_service.GetSomething());
    }
 }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tom Stickel
  • 19,633
  • 6
  • 111
  • 113
  • 3
    Inside the default constructor you're actually using the Service Locator anti-pattern, how do you know the container will have a IExampleService for you? And if it doesn't? on the Index method NullArgumentException, and in design time it looks "fine". This is not using an IoC Container, this applying DI in the wrong way – Ricardo Rodrigues Feb 19 '13 at 10:32