Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a guice injector with two different modules having similar dependencies

Suppose I have two modules ModuleA and ModuleB which are self-sufficient and can be used as stand-alone modules. Both the modules have a dependency on a third module ModuleC like

install(new ModuleC());

Now, I have a use case where I need to create an injector with both modules, A and B. I did this:

Guice.createInjector(new ModuleA(), new ModuleB());

It threw a CreationException as expected which said that a binding to a certain class was already configured at one of the modules. Keeping in mind that I do not have the power to alter ModuleA and ModuleB, how do I make it work?

I tried using Modules.combine(Modules... modules) but that did not solve my problem. Is there any solution out there for this?

like image 915
rrrocky Avatar asked Dec 23 '22 23:12

rrrocky


1 Answers

Consider you have the following bindings defined:

ModuleC:

  • C1

ModuleA

  • A1
  • A2

ModuleB

  • B1
  • B2

Now when you do Guice.createInjector(new ModuleA(),new ModuleB()) or Modules.combine(..), your final list of bindings will be:

  • A1
  • A2
  • B1
  • B2
  • C1 (as inherited from A)
  • C1 (!) (as inherited from B)

as C1 binding is listed twice, that creates a conflict and results in CreationException.

But if you use Modules.override() instead:

Returns a builder that creates a module that overlays override modules over the given modules. If a key is bound in both sets of modules, only the binding from the override modules is kept.

E.g. by doing

Modules.override(new ModuleA()).with(new ModuleB())

Your final list of bindings will be as follows:

  • A1
  • A2
  • B1
  • B2
  • C1 (as inherited from A)
  • C1 (as inherited from B)

The C1 binding inherited from ModuleA will be dropped in favor of the C1 binding as defined in ModuleB, thus resolving the conflict.

like image 188
zeppelin Avatar answered May 25 '23 12:05

zeppelin