Discussion:
Inject a sequence of components that implement the same interface and have dependencies themselves
Dominik
2016-11-07 22:42:57 UTC
Permalink
I want to inject a sequence of components where each component implements
the same interface. Each of the components may have dependencies themselves
which may vary amongst the different implementations of the interface. The
actual sequence shall be configurable by the user by means of a
configuration file or any mechanism that is made available through the
dependency injection framework (guice).

To be more concrete I'll give an example:

interface Machine {...}

class Dishwasher implements Machine {
// Here some dependencies should be injected.
}
class VacuumCleaner implements Machine {
// Here some dependencies should be injected.
}

class Household {
// Here I want to inject a sequence of `Machine`s.
}

// Now the user may specify in whatever way which machines are present in
the household,
// and this setting is not changing during runtime.
// For example (using an arbitrary notation):
//
// Household
// |
// |---- Machines
// |
// |---- Dishwasher
// | |
// | |----- SomeDepedencyForDishwasher
// | |----- AnotherDepedencyForDishwasher
// |
// |----- VacuumCleaner
// | |
// | |----- SomeDependencyForVacuumCleaner
// |
// |----- VacuumCleaner
// | |
// | |----- AnotherDependencyForVacuumCleaner
//
//
// So the household would have three `Machine`s, two of which are
`VacuumCleaner`s
// (where each `VacuumCleaner` itself depends on a different implementation
of another interface)
// and one `Dishwasher`.

How can I realize this using guice? I could write a custom provider for the
`Machine`s (i.e. a `MachineFactory`), however the pattern that "a component
depends on a sequence of others with dependencies themselves" may repeat
further down the chain, so I would be forced to write providers/factories
for all of them. This somehow breaks the purpose of dependency injection
where I can request a component and all dependencies are resolved
automatically by the framework. Furthermore it requires the factory to have
knowledge about the possible dependencies of all implementations of the
interface which breaks the separation of dependencies from the application:
whenever I add a new implementation (a new Machine, e.g. `WashingMaschine`)
I need to check whether the factory already requests all required
dependencies for the `WashingMaschine` in order to "inject" them manually
into the `WashingMaschine` later on. If a new dependency is introduced I
need to fix the factory accordingly.

Any ideas? Thanks! Cheers, Dominik
--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-guice+***@googlegroups.com.
To post to this group, send email to google-***@googlegroups.com.
Visit this group at https://groups.google.com/group/google-guice.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/dc7b7e5c-9019-408e-b883-526bc3120802%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Stephan Classen
2016-11-08 10:38:17 UTC
Permalink
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
Have a look at<br>
<a class="moz-txt-link-freetext" href="https://github.com/google/guice/wiki/Multibindings">https://github.com/google/guice/wiki/Multibindings</a><br>
<br>
this does not solve the problem of how to configure them. But it
allows you to inject a set/map of things.<br>
<br>
<br>
<div class="moz-cite-prefix">On 11/07/2016 11:42 PM, Dominik wrote:<br>
</div>
<blockquote
cite="mid:dc7b7e5c-9019-408e-b883-***@googlegroups.com"
type="cite">
<div dir="ltr">I want to inject a sequence of components where
each component implements the same interface. Each of the
components may have dependencies themselves which may vary
amongst the different implementations of the interface. The
actual sequence shall be configurable by the user by means of a
configuration file or any mechanism that is made available
through the dependency injection framework (guice).<br>
<br>
To be more concrete I'll give an example:<br>
<code><br>
</code>
<div style="background-color: rgb(250, 250, 250); border-color:
rgb(187, 187, 187); border-style: solid; border-width: 1px;
overflow-wrap: break-word;" class="prettyprint"><code
class="prettyprint">
<div class="subprettyprint"><code><span style="color: #008;"
class="styled-by-prettify">interface</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #606;" class="styled-by-prettify">Machine</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #660;" class="styled-by-prettify">{...}</span><span
style="color: #000;" class="styled-by-prettify"><br>
<br>
</span><span style="color: #008;"
class="styled-by-prettify">class</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #606;" class="styled-by-prettify">Dishwasher</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #008;" class="styled-by-prettify">implements</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #606;" class="styled-by-prettify">Machine</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #660;" class="styled-by-prettify">{</span><span
style="color: #000;" class="styled-by-prettify"><br>
    </span><span style="color: #800;"
class="styled-by-prettify">// Here some dependencies
should be injected.</span><span style="color: #000;"
class="styled-by-prettify"><br>
</span><span style="color: #660;"
class="styled-by-prettify">}</span><span style="color:
#000;" class="styled-by-prettify"><br>
</span><span style="color: #008;"
class="styled-by-prettify">class</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #606;" class="styled-by-prettify">VacuumCleaner</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #008;" class="styled-by-prettify">implements</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #606;" class="styled-by-prettify">Machine</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #660;" class="styled-by-prettify">{</span><span
style="color: #000;" class="styled-by-prettify"><br>
</span><span style="color: #000;"
class="styled-by-prettify"></span></code><code><span
style="color: #000;" class="styled-by-prettify"><code
class="prettyprint"><code><span style="color: #000;"
class="styled-by-prettify">    </span><span
style="color: #800;" class="styled-by-prettify">//
Here some dependencies should be injected.</span><span
style="color: #000;" class="styled-by-prettify"><br>
</span></code></code></span><span style="color:
#660;" class="styled-by-prettify">}</span><span
style="color: #000;" class="styled-by-prettify"><br>
<br>
</span><span style="color: #008;"
class="styled-by-prettify">class</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #606;" class="styled-by-prettify">Household</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #660;" class="styled-by-prettify">{</span><span
style="color: #000;" class="styled-by-prettify"><br>
    </span><span style="color: #800;"
class="styled-by-prettify">// Here I want to inject a
sequence of `Machine`s.</span><span style="color:
#000;" class="styled-by-prettify"><br>
</span><span style="color: #660;"
class="styled-by-prettify">}</span><span style="color:
#000;" class="styled-by-prettify"><br>
<br>
</span><span style="color: #800;"
class="styled-by-prettify">// Now the user may specify
in whatever way which machines are present in the
household,</span><span style="color: #000;"
class="styled-by-prettify"><br>
</span><span style="color: #800;"
class="styled-by-prettify">// and this setting is not
changing during runtime.</span><span style="color:
#000;" class="styled-by-prettify"><br>
// For example (using an arbitrary notation):<br>
//<br>
</span></code><code><span style="color: #000;"
class="styled-by-prettify"><code class="prettyprint"><code><span
style="color: #000;" class="styled-by-prettify">//</span></code></code>   
Household<br>
</span></code><code><span style="color: #000;"
class="styled-by-prettify"><code class="prettyprint"><code><span
style="color: #000;" class="styled-by-prettify">//</span></code></code>   
|<br>
</span></code><code><span style="color: #000;"
class="styled-by-prettify"><code class="prettyprint"><code><span
style="color: #000;" class="styled-by-prettify">//</span></code></code>   
|---- Machines<br>
</span></code><code><span style="color: #000;"
class="styled-by-prettify"><code class="prettyprint"><code><span
style="color: #000;" class="styled-by-prettify">//</span></code></code>         
|<br>
</span></code><code><span style="color: #000;"
class="styled-by-prettify"><code class="prettyprint"><code><span
style="color: #000;" class="styled-by-prettify">//</span></code></code>         
|---- Dishwasher<br>
</span></code><code><span style="color: #000;"
class="styled-by-prettify"><code class="prettyprint"><code><span
style="color: #000;" class="styled-by-prettify">//</span></code></code>         
|     |<br>
</span></code><code><span style="color: #000;"
class="styled-by-prettify"><code class="prettyprint"><code><span
style="color: #000;" class="styled-by-prettify">//</span></code></code>         
|     |----- SomeDepedencyForDishwasher</span></code><br>
<code><span style="color: #000;"
class="styled-by-prettify"><code class="prettyprint"><code><span
style="color: #000;" class="styled-by-prettify"><code
class="prettyprint"><code><span style="color:
#000;" class="styled-by-prettify">//</span></code></code>         
|     |----- AnotherDepedencyForDishwasher</span></code></code><br>
</span></code><code><span style="color: #000;"
class="styled-by-prettify"><code class="prettyprint"><code><span
style="color: #000;" class="styled-by-prettify">//</span></code></code>         
|<br>
</span></code><code><span style="color: #000;"
class="styled-by-prettify"><code class="prettyprint"><code><span
style="color: #000;" class="styled-by-prettify">//</span></code></code>         
|----- VacuumCleaner</span></code><br>
<code><span style="color: #000;"
class="styled-by-prettify"><code class="prettyprint"><code><span
style="color: #000;" class="styled-by-prettify"><code
class="prettyprint"><code><span style="color:
#000;" class="styled-by-prettify">//</span></code></code>         
|     |<br>
</span></code></code></span></code><code><span
style="color: #000;" class="styled-by-prettify"><code
class="prettyprint"><code><span style="color: #000;"
class="styled-by-prettify"><code
class="prettyprint"><code><span style="color:
#000;" class="styled-by-prettify">//</span></code></code>         
|     |----- SomeDependencyForVacuumCleaner</span></code><code><span
style="color: #000;" class="styled-by-prettify"><br>
</span></code></code></span></code><code><span
style="color: #000;" class="styled-by-prettify"><code
class="prettyprint"><code><span style="color: #000;"
class="styled-by-prettify"><code
class="prettyprint"><code><span style="color:
#000;" class="styled-by-prettify">//</span></code></code>         
|</span></code></code></span></code><br>
<code><span style="color: #000;"
class="styled-by-prettify"><code class="prettyprint"><code><span
style="color: #000;" class="styled-by-prettify"><code
class="prettyprint"><code><span style="color:
#000;" class="styled-by-prettify">//</span></code></code>         
|----- VacuumCleaner</span></code><br>
<code><span style="color: #000;"
class="styled-by-prettify"><code
class="prettyprint"><code><span style="color:
#000;" class="styled-by-prettify"></span></code></code></span></code></code></span></code><code><span
style="color: #000;" class="styled-by-prettify"><code
class="prettyprint"><code><span style="color: #000;"
class="styled-by-prettify"><code
class="prettyprint"><code><span style="color:
#000;" class="styled-by-prettify"><code
class="prettyprint"><code><span
style="color: #000;"
class="styled-by-prettify">//</span></code></code>         
|     |<br>
</span></code></code></span></code></code></span></code><code><span
style="color: #000;" class="styled-by-prettify"><code
class="prettyprint"><code><span style="color: #000;"
class="styled-by-prettify"><code
class="prettyprint"><code><span style="color:
#000;" class="styled-by-prettify"><code
class="prettyprint"><code><span
style="color: #000;"
class="styled-by-prettify">//</span></code></code>         
|     |-----
AnotherDependencyForVacuumCleaner</span></code><code><span
style="color: #000;"
class="styled-by-prettify"><br>
</span></code></code></span></code></code></span></code><code
class="prettyprint"><code><span style="color: #000;"
class="styled-by-prettify">//</span></code></code><br>
<code><span style="color: #000;"
class="styled-by-prettify"><code class="prettyprint"><code><span
style="color: #000;" class="styled-by-prettify">//</span></code></code><br>
// So the household would have three `Machine`s, two
of which are `VacuumCleaner`s<br>
// (where each `VacuumCleaner` itself depends on a
different implementation of another interface)<br>
// and one `Dishwasher`.<br>
</span></code></div>
</code></div>
<br>
How can I realize this using guice? I could write a custom
provider for the `Machine`s (i.e. a `MachineFactory`), however
the pattern that "a component depends on a sequence of others
with dependencies themselves" may repeat further down the chain,
so I would be forced to write providers/factories for all of
them. This somehow breaks the purpose of dependency injection
where I can request a component and all dependencies are
resolved automatically by the framework. Furthermore it requires
the factory to have knowledge about the possible dependencies of
all implementations of the interface which breaks the separation
of dependencies from the application: whenever I add a new
implementation (a new Machine, e.g. `WashingMaschine`) I need to
check whether the factory already requests all required
dependencies for the `WashingMaschine` in order to "inject" them
manually into the `WashingMaschine` later on. If a new
dependency is introduced I need to fix the factory accordingly.<br>
<br>
Any ideas? Thanks! Cheers, Dominik<br>
</div>
-- <br>
You received this message because you are subscribed to the Google
Groups "google-guice" group.<br>
To unsubscribe from this group and stop receiving emails from it,
send an email to <a moz-do-not-send="true"
href="mailto:google-guice+***@googlegroups.com">google-guice+***@googlegroups.com</a>.<br>
To post to this group, send email to <a moz-do-not-send="true"
href="mailto:google-***@googlegroups.com">google-***@googlegroups.com</a>.<br>
Visit this group at <a moz-do-not-send="true"
href="https://groups.google.com/group/google-guice">https://groups.google.com/group/google-guice</a>.<br>
To view this discussion on the web visit <a
moz-do-not-send="true"
href="https://groups.google.com/d/msgid/google-guice/dc7b7e5c-9019-408e-b883-526bc3120802%40googlegroups.com?utm_medium=email&amp;utm_source=footer">https://groups.google.com/d/msgid/google-guice/dc7b7e5c-9019-408e-b883-526bc3120802%40googlegroups.com</a>.<br>
For more options, visit <a moz-do-not-send="true"
href="https://groups.google.com/d/optout">https://groups.google.com/d/optout</a>.<br>
</blockquote>
<br>
</body>
</html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &quot;google-guice&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:google-guice+***@googlegroups.com">google-guice+***@googlegroups.com</a>.<br />
To post to this group, send email to <a href="mailto:google-***@googlegroups.com">google-***@googlegroups.com</a>.<br />
Visit this group at <a href="https://groups.google.com/group/google-guice">https://groups.google.com/group/google-guice</a>.<br />
To view this discussion on the web visit <a href="https://groups.google.com/d/msgid/google-guice/5821AB19.4020305%40gmx.ch?utm_medium=email&utm_source=footer">https://groups.google.com/d/msgid/google-guice/5821AB19.4020305%40gmx.ch</a>.<br />
For more options, visit <a href="https://groups.google.com/d/optout">https://groups.google.com/d/optout</a>.<br />
Loading...