Hi,
Sam and others have commented on this quite well, but let me clarify one
thing.
You're describing, as Sam said, Service Locator pattern. This, like
Dependency Injection, is a kind of "Inversion of Control" - but it is
not the Dependency Injection pattern. Eclipse/OSGI, and others employ
this Service Locator pattern. I have seen people USE Guice to simulate
this pattern, but that is not what it was designed for.
Other than this, Sam's comments reflect my own views.
* Don't inject the injector where you can in any way avoid it
* Don't inject value types - if necessary and relevant, inject
factories that produce them.
* Inject "collaborators" - objects which rely on each others'
behavior
* Don't try to structure global access to your injector, make the app
manifested buy the injector, and have all its dependencies injected.
Some people jokingly simplify D-I and say "it's a map, essentially".
That's only sort of true, and is an implementation detail. Automated
D-I is simply a framework for wiring together all of the
components/objects of your system. Service Locator is a different way,
but they both attempt to get at a separation of parts, a decoupling.
D-I relies more on the "Hollywood Principle" - "Don't call us, we'll
call you." That is, your code (except for the very earliest startup
code) should not be calling Guice, it should be specifying (in the
constructor or in injectable fields/methods) what it needs. Guice will
call your code appropriately so as to wire it all up with the
dependencies you have so specified. The only code you should have that
relies on Guice itself is your Module code which is configuration of the
guice bindings, and the startup code which initializes the graph of
objects. Your application code itself should have little or no
knowledge of Guice or Guice's internals.
I hope that clarifies the difference a little bit.
cheers,
Christian.
On 11 Nov 2013, at 7:03, Alan Darkworld wrote:
Hello everyone,
I've been working with Java for several years now and I'm always open
for
new ideas to improve code quality. But I do have some serious doubts
about
dependency injection (more on that later). However, as large
frameworks
such as Eclipse 4 and Xtext employ it successfully, I'm trying to get
used
to this new idiom. When walking through some tutorials, several
questions
appeared:
*1)* The Injector becomes a sort of "main static factory" for the
entire
application. However, Guice does not instance-control the injector -
in
other words, Injector#getInstance is not static. How do you share your
injector across all classes in your application such that it's easy to
access? The easiest thing I can think of is to create it once at the
start
of the program and then make it available through a static field, but
that
just doesn't feel "right" to me.
*2)* I can see that DI is handy if all objects have no-argument
default
constructors. But most of the time, this is not the case, especially
with
immutable objects that need to check their invariants in their
constructor.
Consider for example an immutable "DateRange" class with the invariant
"start date < end date". The only valid constructor for this class has
two
parameters (the dates), yielding a client code like:
long start = calculateStart(); // calculates the start time based on
user
input (result is dynamic)
long end = calculateEnd(); // calculates end time based on user
input
(result is dynamic)
DateRange period = new DateRange(start, end); // throws
IllegalArgumentException if start > end), need to replace this line by
Depencency Injection
How would something like this translate into the Dependency Injection
idiom? I can clearly see DI working for the Java Beans pattern, but
what
about the immutable case? I've had a look at the Guice Documentation,
but I
couldn't spot an answer to this.
*3)* For many years, several books (including the excellent
"*Effective
Java*") have gone to great lenghts explaining how to keep our class
invariants safe from both malicious access and careless programmers
(including client use and subclassing). By applying DI, we forfeit the
control over our fields, we give up on encapsulation. From my point of
view, with DI the focus has shifted from "*This class will work, no
matter
how much you mistreat it*" to "*It works if you treat it right,
otherwise
it's your own fault*". What implications does that have for software
quality? We sure gain a lot in terms of configurability (create a new
subclass, introduce it in the module and you're all set), but what do
we
lose with respect to safety and contracts? This is actually my main
concern
about DI and the very reason why I can't yet wrap my head around it.
Can
somebody provide a reason why my concerns are without cause? Please
do!
I do have some more concerns about DI, but the three stated above are
the
ones which really prevent me from getting into it. I'd be grateful if
someone could explain how to do it the right way (for 1 and 2), or why
I'm
wrong (for 3).
Thanks,
Alan
--
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice.
For more options, visit https://groups.google.com/groups/opt_out.
Christian Gruber :: Google, Inc. :: Java Core Libraries :: Dependency
Injection
email: [email protected] :::: mobile: +1 (646) 807-9839
--
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice.
For more options, visit https://groups.google.com/groups/opt_out.