Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do manual DI with deep object graphs and many dependencies properly

I believe this questions has been asked in some or the other way but i'm not getting it yet.

We do a GWT project and my project leader disallowed to use GIN/Guice as an DI framework (new programmers are not going to understand it, he argued) so I try to do the DI manually.

Now I have a problem with deep object graphs. The object hierarchy from the UI looks like this:

AppPresenter->DashboardPresenter->GadgetPresenter->GadgetConfigPresenter

The GadgetConfigPresenter way down the object hierarchy tree has a few dependencies like CustomerRepository, ProjectRepository, MandatorRepository, etc.

So the GadgetPresenter which creates the GadgetConfigPresenter also has these dependencies and so on, up to the entry point of the app which creates the AppPresenter.

  • Is this the way manual DI is supposed to work?
  • doesn't this mean that I create all dependencies at boot time even I don't need them?
  • would a DI framework like GIN/Guice help me here?
like image 982
Fabian Avatar asked Mar 11 '10 14:03

Fabian


People also ask

What is DI how an object can get dependencies?

Dependency Injection (DI) is a programming technique that makes a class independent of its dependencies. “In software engineering, dependency injection is a technique whereby one object supplies the dependencies of another object. A 'dependency' is an object that can be used, for example as a service.

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.

How many methods are there in the dependency objects?

There are three types of dependency injection — constructor injection, method injection, and property injection.

What type of design pattern is dependency injection?

In software engineering, dependency injection is a design pattern in which an object or function receives other objects or functions that it depends on. A form of inversion of control, dependency injection aims to separate the concerns of constructing objects and using them, leading to loosely coupled programs.


1 Answers

You write that

the GadgetPresenter which creates the GadgetConfigPresenter[.]

Instead of directly creating GadgetConfigPresenter instances, GadgetPresenter should take a dependency on an Abstract Factory that can create GadgetConfigPresenter instances for it. This pushes the inner dependencies of GadgetConfigPresenter to the factory.

Using Constructor Injection all the way, your Poor Man's DI wiring should look something like this (apologies for the C# syntax):

var customerRepository = new CustomerRepository(/*...*/);
var projectRepository = new ProjectRepository(/*...*/);
var mandatorRepository = new MandatorRepository(/*...*/);

var gadgetConfigPresenterFactory = 
    new GadgetConfigPresenterFactory(
        customerRepository,
        projectRepository,
        mandatorRepository);

var gadgetPresenter = new GadgetPresenter(gadgetConfigPresenterFactory);
var dashboardPresenter = new DashboardPresenter(gadgetPresenter);
var appPresenter = new AppPresenter(dashboardPresenter);

Notice how we break the dependency chain often, ensuring that the number of dependencies for each consumer never becomes too big.

In principle, this means that you must create all the dependencies at boot time, unless you implement a lazy loading strategy.

Such things as managing lifetimes are exactly the sort of thing where a DI Container can be enormously helpful, but it's entirely possible to write an entire application by just following DI patterns and principles.

All in all, though, I would still recommend a DI Container if at all possible.

like image 64
Mark Seemann Avatar answered Oct 10 '22 06:10

Mark Seemann