Is this a good example of the “Bastard injection a

2019-02-06 00: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()) { }

回答1:

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.



回答2:

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());
    }
 }