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. 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 On Tue, May 10, 2011 at 9:47 AM, Mingfai <[email protected]> wrote: > hi, > >> >> 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. > > perhaps you could elaborate on how your refactoring is broken by Guice. > > If you inject by type (and optionally custom annotation), the refactoring > function of any IDE could change anything that Guice needs to know. Say you > have an "@Inject MyInterface myInterface;", when you rename the MyInterface > to MyInterface2, the refactoring won't break Guice's configuration. > > There are many things IDE won't do it for you. If you heavily use @Named, > your IDE can't refactor the name for you as it is only a String. One simple > solution is to use a constant, another option is to use custom annotation. > Take an extreme example, if you inject everything as Object like "@Inject > @Named("XXX") Object anything;", you could create a mess with Guice. But > normally, you use a proper type so your IDE can recognize, and annotation is > optional. Another thing IDE won't refactor for you is when you inject an > interface, your IDE won't know the concrete implementation. To me, it is > expected and obviously not a problem, you could use "Find Usages" in IDEA to > locate to relevant module easily. > > For other frameworks like Spring that put the configuration in XML, you do > need IDE support. For Guice, it's all Java and it doesn't really need IDE > support. What IDE help you expect? > > >> >> 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? > > yes, you should do unit testing anyway. For me, when i write a new module, i > usually start with write a new test case to test the module. But, IMHO, > moving to Guice doesn't really reduce your compile time checking. For your > custom factories, if you code them incorrectly, you won't know the problem > until runtime as well. > > >> >> 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. > > You won't easily know what class a module is providing unless you design > your module in a consistent way and/or with documentation. there are many > place you could configure binding, e.g. in the configure() method, bind a > provider class (class XXX implements Provider<YYY>), use @Provides in the > module class, from a child/binder module (such as MapBinder) , using custom > injection etc. if you want to know where is a the provider of a particular > interface, you could just use the search function of your IDE. (e.g. Find > Usages for IDEA) > > For me, i like to use (up to) one module per package for my own classes, and > a Guice module will provide only class in the same package or sub-packages. > when i use a third-party library, I usually create a module dedicate for > providing injection for classes from that library. This gives me a good idea > where those injections come from, and allow me to unit test them > independently. > > Guice mainly inject by type and annotation. Say if you have a class Apple > with default constructor, the injection "@Inject Apple apple;" will work > without any configuration. Say if you want to inject an interface Fruit > (where Apple implements Fruit), you need to configure a binding in some way, > e.g. in a module with " binder.bind(Fruit.class).to(Apple.class)" or use > Just-In-Time binding annotation. For both cases, @Inject is enough because > Guice could locate the binding by type. Say if you have multiple Fruit that > you want to inject in different place, you will need to use annotation to > tell Guice which is which. e.g. > @Inject @Named("apple") Fruit apple; // configure by > binder.bind(Fruit.class).annotatedWith(Names.named("apple")).to(Apple.class) > > if you are not sure if you are using Guice properly, maybe you could just > post your scenario and ask for other ppl's comment. We can't tell whether > your are doing wrong without a concrete case. > > regards, > mingfai > > -- > You received this message because you are subscribed to the Google Groups > "google-guice" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/google-guice?hl=en. > -- You received this message because you are subscribed to the Google Groups "google-guice" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.
