--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To post to this group, send email to google...@googlegroups.com.
To unsubscribe from this group, send email to google-guice...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.
1. No IDE help. I use IDEA and as of yet it is not Guice aware so all
my refactoring/code support is broke. And I have to build the modules
by hand which is just as hard as making the factory manually before I
used Guice. So to me Guice just moves the problem around. At least
when I made manual factories the IDE could keep changes in sync.
2. Loss of compile time checking. Just by running the compiler I
can't tell if my code is complete, by that I mean have all the right
modules/parameters, I don't find out something is wrong until
runtime. Prior to this, using manual factories, this was a given.
Perhaps I need to add a unit test that forces Guice to create an
instance of the class so it least I could know during the test phase
that the module/factory is correct?
3. Can't keep track of all the modules. As best I can tell nothing in
the module code even says what class it's a factory for. There is too
much annotation magic going on, apparently @Inject is enough for Guice
to 'know' that someplace in vast numbers of Guice modules there should
be one that has the right mix of input parameters?
What am I doing wrong? I feel like this is a couple steps in the
wrong direction.
Regarding 1 at a minimum I need the code/refactoring support one would
get if using manual factories. E.g. If I add a constructor parameter
or change parameter order I need it to keep the module/factory in
sync. In IDEA reordering would change it everywhere, adding something
new would have a default value. So it should at least add another
bind() to the module where I have to fill out the types (and fail to
compile until I do). As it is now I have to manually keep both in
sync. My IDE has become Notepad.
As a bonus the IDE should create the module as else the module really
doesn't save any coding. But I understand this is not a Guice problem
it's a desired IDE feature.
1b. Another example, with Guice I can't even ask the IDE to find uses
of a constructor so I can find where it's used/created because that
usage is hidden behind the magic of annotations. Again my IDE has
become Notepad.
2. In the module for a class (which is its factory) I can have
completely wrong bind statements and the compiler doesn't care. It's
not until runtime that errors are seen. Unit tests generally use
mocks (that's why its IoC) so that won't catch the error either. I
can add another test...really an integration test that causes Guice to
create a live instance...that should catch any problems...but I'm
concerned about that working in the general case because sometimes
that will require lots of application code to fire up...not what is
desired in a unit test.
I guess my point here is that with manual factories those didn't need
to be unit tested because with the compiler's help those are
binary...you either have one or you don't...nothing really to test.
With Guice lots can go wrong in the factory (Module). And because I
have no IDE help to maintain the module...lots does go wrong.
3. I'll review and see if I can make improvements in how I manage
modules. To start I just had one package for these for the app...that
was no good so now I name the module the same as the class with Module
suffix and put in the same package as the class, that way I know where
it is. I have one master class where I new up all the modules and add
to Guice.createInjector(). Not sure yet how this will work.
Thanks again for you help...
-Dave
Thanks for the reply...Regarding 1 at a minimum I need the code/refactoring support one would
get if using manual factories. E.g. If I add a constructor parameter
or change parameter order I need it to keep the module/factory in
sync. In IDEA reordering would change it everywhere, adding something
new would have a default value. So it should at least add another
bind() to the module where I have to fill out the types (and fail to
compile until I do). As it is now I have to manually keep both in
sync. My IDE has become Notepad.
As a bonus the IDE should create the module as else the module really
doesn't save any coding. But I understand this is not a Guice problem
it's a desired IDE feature.1b. Another example, with Guice I can't even ask the IDE to find uses
of a constructor so I can find where it's used/created because that
usage is hidden behind the magic of annotations. Again my IDE has
become Notepad.
2. In the module for a class (which is its factory)
I can have
completely wrong bind statements and the compiler doesn't care.
It's
not until runtime that errors are seen. Unit tests generally use
mocks (that's why its IoC) so that won't catch the error either. I
can add another test...really an integration test that causes Guice to
create a live instance...that should catch any problems...but I'm
concerned about that working in the general case because sometimes
that will require lots of application code to fire up...not what is
desired in a unit test.I guess my point here is that with manual factories those didn't need
to be unit tested because with the compiler's help those are
binary...you either have one or you don't...nothing really to test.
With Guice lots can go wrong in the factory (Module). And because I
have no IDE help to maintain the module...lots does go wrong.
Class A takes 4 parameters where all are interfaces of course. I add
@Inject annotation to the constructor and optionally scope annotation
to the class. I then create a module for this class that extends from
AbstractModule that implements configure. In this method I create and
maintain 4 bind() method calls that map the interface to the actual
class. I assume the order of these bind statements much match the
order in the constructor. Repeat for every IoC class in the
application.
I guess I just don't get your comment 'bind()ings are about *what* to
inject, not *where* to inject them.' It seems you need some way to
specify the *where* too.
-Dave
Peter
1. Hum, perhaps I'm doing more work than I need to...perhaps just out
of habit of previously using manual factories...but I think I got this
from the Guice online docs. Here is what I do:Class A takes 4 parameters where all are interfaces of course. I add
@Inject annotation to the constructor and optionally scope annotation
to the class. I then create a module for this class that extends from
AbstractModule that implements configure. In this method I create and
maintain 4 bind() method calls that map the interface to the actual
class. I assume the order of these bind statements much match the
order in the constructor. Repeat for every IoC class in the
application.
I guess I just don't get your comment 'bind()ings are about *what* to
inject, not *where* to inject them.'
It seems you need some way to
specify the *where* too.
Thanks for the reply...
Regarding 1 at a minimum I need the code/refactoring support one would
get if using manual factories. E.g. If I add a constructor parameter
or change parameter order I need it to keep the module/factory in
sync. In IDEA reordering would change it everywhere, adding something
new would have a default value.
So it should at least add another
bind() to the module where I have to fill out the types (and fail to
compile until I do). As it is now I have to manually keep both in
sync. My IDE has become Notepad.
As a bonus the IDE should create the module as else the module really
doesn't save any coding. But I understand this is not a Guice problem
it's a desired IDE feature.
1b. Another example, with Guice I can't even ask the IDE to find uses
of a constructor so I can find where it's used/created because that
usage is hidden behind the magic of annotations. Again my IDE has
become Notepad.
--
I think I'm starting to 'get' it. Having just one Module with the 'configuration' sure is a lot simpler. In cases where I need to map to a specific implementation I used this approach:
@Named("MyImpl")
&
bind(IMyInterface.class).annotatedWith(Names.named("MyImpl")).to(MyImpl.class);
That seems pretty simple. I still think/hope the IDE can be smart and make sure that if I annotate with @Inject it will let me know and/or help me make sure all the parameters have been specified in the 'configuration'.
David,
You make some valid points about some of the drawbacks of using Guice
and probably IoC in general, I've struggled to get the concept of
dependency injection to catch on in my office because of some of the
reasons you mention.
Its really a trade-off, by using an IoC container to wire your classes
together you might be losing some compile-time checking that you would
have by calling constructors directly, or calling factory methods, but
that route will lead you down a path to a very tightly coupled
application, that is not able to adapt to changing requirements or the
addition of new functionality. You could say similar things about
using interfaces, using lots of interfaces in your code makes it
somewhat harder to read and follow what's going on, but I think most
agree that using interfaces in logical places is beneficial and helps
to create a loosely coupled application. Another huge benefit of using
IoC is the vast improvements you'll see in the testability of your
code.
With respect to your complaint about not finding out about missing
bindings until runtime (2), this is definitely true, but I've found
that you discover the missing bindings pretty quickly as soon as you
try to start your application for the first time, and maybe run a
happy path scenario test. Misko talks about this a little bit in his
unit testing tech talk (http://www.youtube.com/watch?v=wEhu57pih5w).
Guice also supports a "PRODUCTION" mode (or Stage:
http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/Stage.html)
which will create all singletons eagerly and help expose missing
bindings at startup.
I sympathize with your issues of keeping track of modules, working on
a large project we struggled with module organization also as we
started using Guice in more and more places. We started with a module
per application approach, but this caused a lot of duplicate code in
different modules and forced developers to have to understand the guts
of other developer's code. We finally settled on a module per
"service" strategy, service is a pretty vague term in this context but
it's generally composed of a group of related classes. With this
approach, if one developer decides to use a service written by
another, they know they need to install the module associated with
that service. It seems to be working reasonably well so far, but
you'll likely have to experiment with different approaches and
determine the one that works well for your development environment.
On May 9, 11:38 pm, dhoffer <dhoff...@gmail.com> wrote:
> Okay I'm new to Guice so maybe I'm missing something but since I
> converted one app to use Guice I've found some things that I just
> don't like, I'm wondering if folks have found solutions or have
> suggestions.
>
> 1. No IDE help. I use IDEA and as of yet it is not Guice aware so all
> my refactoring/code support is broke. And I have to build the modules
> by hand which is just as hard as making the factory manually before I
> used Guice. So to me Guice just moves the problem around. At least
> when I made manual factories the IDE could keep changes in sync.
>
> 2. Loss of compile time checking. Just by running the compiler I
> can't tell if my code is complete, by that I mean have all the right
> modules/parameters, I don't find out something is wrong until
> runtime. Prior to this, using manual factories, this was a given.
> Perhaps I need to add a unit test that forces Guice to create an
> instance of the class so it least I could know during the test phase
> that the module/factory is correct?
>
> 3. Can't keep track of all the modules. As best I can tell nothing in
> the module code even says what class it's a factory for. There is too
> much annotation magic going on, apparently @Inject is enough for Guice
> to 'know' that someplace in vast numbers of Guice modules there should
> be one that has the right mix of input parameters?
>
> What am I doing wrong? I feel like this is a couple steps in the
> wrong direction.