Discussions

News: Dependency injection with Guice

  1. Dependency injection with Guice (20 messages)

    Guice is Google's open source dependency injection framework for Java development. It enables better testing and modularity by taking away the pain of writing your own factories. This article offers a tour of the most important Guice concepts that will leave you ready to Guice up your applications.

    Threaded Messages (20)

  2. "Some engineers dislike the idea of adding an @Inject to their class. They prefer that a class be totally ignorant of the DI framework. This is a reasonable point, but I'm not convinced by it. As dependencies go, an annotation is pretty mild. The @Inject tag takes on meaning only when you ask Guice to construct your class." This is incorrect. The "@Inject" annotation takes meaning as soon as it is added to the Java code. After the annotation is added, it is no longer possible to compile the code without Guice. Add the annotation and you've injected one more dependency to your project. Having said that... why do all the articles that praise Guice exclude the import statements from the Java code examples? Embarrassed maybe?
  3. Having said that... why do all the articles that praise Guice exclude the import statements from the Java code examples? Embarrassed maybe?
    Personally, I find the imports in code examples to be useless noise. I can always copy and paste the code, press Shift-Command-I (NetBeans on the Mac FTW! :) and move on. Having to wade through all of that in someone's blog entry adds zero value to the discussion, unless the discussion is "Look at all those imports!" :)
  4. "... The @Inject tag takes on meaning only when you ask Guice to construct your class." After the annotation is added, it is no longer possible to compile the code without Guice. Add the annotation and you've injected one more dependency to your project.
    The original meaning of "meaning" is at runtime, not compile time. Sure, compile time dependency may not be 100% ideal, but IMHO, it's not that bad either. You still can use any class annotated with @Inject outside of a Guice runtime. Projects that use IoC can have plenty of unit tests (and other runtime scenarios) that don't need Guice to manage the runtime behavior of your objects.
  5. What's interesting is that (from my glance at the article, being otherwise ignorant of Guice) it seems that you can add your own annotations in order to provide selectivity to what "types" of objects are injected (i.e. the "Fast" example with @Fast). By the same token, you'd like to think it would be a minor tweak to change the Guice supplied @Inject annotation with a project supplied @MyInject annotation. Assuming @Inject is simply a marker annotation (without other parameters), it should be straightforward to augment Guice by making the annotation used for marking Injection a parameter to the framework. Then you could fire up Guice, tell it to use @MyInject, and then you'd have no external dependencies within (the bulk of) your code. Only that code that relied on the Guice Factory would be dependent, and even that could likely be refactored to a single class or set of classes making your framework reliance quite isolated.
  6. Hi, Will. Kevin B. recently answered this question on the Guice mailing list (http://groups.google.com/group/google-guice/browse_thread/thread/323cc1f4e6b074e5):
    First off, your code is going to depend on some interfaces like Module and Provider anyway, so your change with the annotations doesn't really change anything. I do think it would make sense for us to put these common interfaces and annotations into their own small JAR file, so you can feel more light and airy when you depend on only that, and there is a feature request filed for it (I don't remember if Bob and Jesse agree, though). Beyond that, I think that some people, when seeing "import com.google.inject.Inject", simply imagine a problem where none really exists. We all work so hard at keeping dependencies out of our code that when we see that we react against it at a gut level. But in reality, your classes have no runtime dependency on Guice. If they run as part of an application that doesn't wish to use Guice, the Guice jar file needn't even be present on the server at all. The idea of "dependency" or "tight coupling" is that "the one cannot function without the other." But with annotations, this isn't the case. They're just decoration that don't, and can't, actually do anything. They sit there, innocuously, in case tools will wish to read them, and otherwise have no effect whatsoever. They don't impede you from testing your code, or from using the classes with Spring or just using them normally. Hopefully this explains why we have never been convinced there's an actual problem here.
  7. Hopefully this explains why we have never been convinced there's an actual problem here.
    The size of the JAR is not an issue. The issue is that the JAR file exists and is needed. The problem is the Guice dependency that is added to the code. The number of extra JAR files I need is greater than 0. If I want to use Spring, I still need Guice to compile. If I ask it a bit differently, then maybe then my point is clearer: Please provide a list of all the DI frameworks that my code should support. DI frameworks are supposed to support the code. Not the other way around. Guice makes some neat tricks, but it fails because it makes the assumption that it is the universal solution.
  8. Hopefully this explains why we have never been convinced there's an actual problem here.


    The size of the JAR is not an issue. The issue is that the JAR file exists and is needed.

    The problem is the Guice dependency that is added to the code. The number of extra JAR files I need is greater than 0. If I want to use Spring, I still need Guice to compile. If I ask it a bit differently, then maybe then my point is clearer:

    Please provide a list of all the DI frameworks that my code should support.


    DI frameworks are supposed to support the code. Not the other way around. Guice makes some neat tricks, but it fails because it makes the assumption that it is the universal solution.
    I am not a Guice user (we are still on 1.4 at work) but I think to be fair, Bob Lee is actually trying to put the power back in the hands of the developer whereas Spring tries to wipe your ass for you. On the other hand, I actually quite agree that the issue you are pointing to is quite a real one. But I see it as a flaw with annotations. I used to use xdoclet back in the day and as crude as it is compared to annotations it was nice that all you added to your code was comments and nothing broke if you dropped xdoclet.
  9. Use the Context IoC design pattern. I have been using it since Java 1.3 and works great. See article http://www.theserverside.com/tt/articles/content/IOCandEJB/article.html The article needs an update (in progress..) but mostly still applies.
  10. After the annotation is added, it is no longer possible to compile the code without Guice.
    Same story with a lot of other things, but there is nothing stopping you from mapping the standard javax.annotations.Resource to act as that @Inject annotation. @Resource could be used instead of @Inject...
  11. "Some engineers dislike the idea of adding an @Inject to their class. They prefer that a class be totally ignorant of the DI framework. This is a reasonable point, but I'm not convinced by it. As dependencies go, an annotation is pretty mild. The @Inject tag takes on meaning only when you ask Guice to construct your class."

    This is incorrect. The "@Inject" annotation takes meaning as soon as it is added to the Java code. After the annotation is added, it is no longer possible to compile the code without Guice. Add the annotation and you've injected one more dependency to your project.

    Having said that... why do all the articles that praise Guice exclude the import statements from the Java code examples? Embarrassed maybe?
    I am not agree... We use Guice a lot (after using Spring a lot) and we find that Guice brings a far better design than Spring for example, and reduce code. For sure you will have @Inject in your code, but with Spring, you also may have @Autowired, InitializingBean, Spring annotations / super classes in your tests, spring super classes for Hibernate of you use the HibernateTemplate, ... Spring may be everywhere in your code. Guice is specialized and it does very well what it is supposed to do: dependency injection. Spring is just a factory for your beans. If you compare the IOC features of both i think Guice is better. 1. Guice forces better design in your code: you can take advantage of package view to limit the visibility of your implementation, that you and only you control and can modify without impact, and just provides interfaces to the public world. With Spring, every bean in the xml must be public. So client code may use directly your implementations (and you must know them to create a spring context). So you often have a public interface along with its public implementation... And you see developers ending up using directly the implementation as declared in spring xml file... 2. @Inject is not intrusive since you choose Guice as your DI framework and you control your implementations. Personally, i prefer writing this in my package org.service public interface Service {void load();} final class MyService { @Inject Dao myDao; // Dao being an interface provided by a module @Inject Provider session; // provides new sessions each time public void load() {session.get(); [...] } } than public final class MyService { // private fields public MyService(Dao dao, SessionFactory session) { // this.XXX = XXX; } public void load() {{session.get(); [...]} } The code in the load() method won't change: what changes is how you instanciate the class and provide dependencies to it. Guice does the job better i think. It does not force you to use traditional getter / setter methods and ctors, and also does not force you to expose you implementation to the public world. With Guice you can do better with fewer code !
  12. I have never used this technology but WHY use annotations when you have to write classes like this
    public class HeroModule implements Module { public void configure(Binder binder) { binder.bind(Vehicle.class).to(FrogMobile.class); } } @Inject public FrogMan(Vehicle vehicle) { this.vehicle = vehicle; } public class Adventure { public static void main(String[] args){ Injector injector = Guice.createInjector(new HeroModule()); FrogMan hero = injector.getInstance(FrogMan.class); hero.fightCrime(); } }
    Which in my view are just plain old factories. Furthermore I dislike programming something that is clearly configuration and has no business in code. When you want to switch implementation you have to recode this and deploy it. Where with something like Spring you can change your configuration and be done with it. Furthermore I think it is a good practice to be somewhat verbose in coding. It is hard enough to read your own code after a while, let alone someone else. I do not reccommend to hide code use shortcuts just because the programmer is lazy and unwilling to do some work. M2C
  13. Well, I for one would prefer using the Constructor over @Inject on the fields (and I'm pretty sure I read somewhere Bob Lee has this preference as well). The reason being that it can enable you to make the fields final and that has the benefit in terms of the Java Memory Model and concurrency/thread safety. Refer to: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#finalRight So for me this means the Constructor is by far the preferred method where possible (I'm a fan of final fields where possible) and setter method or field injection the poor cousin. Additionally I'd guess and say those people favoring Constructor injection have more aversion to requiring @Inject - they question why it is needed at all - perhaps there is a good reason for it but it is not clear to me.
  14. Hmmm... looks like I was wrong ?[ Go to top ]

    Looks like I was wrong WRT Bob's preference... http://markmail.org/message/fxs5k32dihpoy5ry#query:bob%20lee%20constructor%20injection+page:1+mid:fxs5k32dihpoy5ry+state:results
    I actually shouldn't have mentioned the semantics of final. The important thing is that all injection happens in a single thread, so there are no concurrency concerns w/ field vs. constructor injection. Bob
    Hmmm. Rather interesting because in my mind I think of final fields as having the visibility of volatile at construction - but dynamically changing a final field (via reflection) after construction would not quite be the same thing and I wonder if it provides the same visibility?? I wonder why Bob thinks it would? "all injection happens in a single thread" - very interesting... but again this doesn't provide the visibility guarantee that final fields or volatile provides? I must be missing something...
  15. And here it is... http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf 9.1.1 Post-Construction Modification of Final Fields ... Freezes of a final field occur both at the end of the constructor in which the final field is set, and immediately after each modification of a final field via reflection other special mechanism. ...
  16. Re: Hmmm... looks like I was wrong ?[ Go to top ]

    Looks like I was wrong WRT Bob's preference...
    I strongly prefer constructor injection. That's actually one of the primary reasons I created Guice (other frameworks didn't handle it well). In the rare cases where I do use field injection, I typically don't make the fields final.
  17. Re: Hmmm... looks like I was wrong ?[ Go to top ]

    Looks like I was wrong WRT Bob's preference...


    I strongly prefer constructor injection. That's actually one of the primary reasons I created Guice (other frameworks didn't handle it well).

    In the rare cases where I do use field injection, I typically don't make the fields final.
    Is it feasible to use Guice without using field based injection? What are the cases you find you need to use field-based injection?
  18. Re: Hmmm... looks like I was wrong ?[ Go to top ]

    Is it feasible to use Guice without using field based injection? What are the cases you find you need to use field-based injection?
    Field injection is useful for pre-constructed objects. I use it when I'm not going to unit test code directly. For example: bind(Foo.class).toProvider(new Provider() { @Inject Bar bar; public Foo get() { ... } });
  19. 2 cents[ Go to top ]

    You know, I'm going to eventually get the name "2 cent" on here. Anyway, having used Seam/EJB this time around for a client, I have to say I'm not all that impressed with DI. It's more to learn, you have to pay close attention to what you're doing just to make it work at all, it makes testing quirky since it's all "in container", and it just doesn't buy you much. By all means, if there's something DI gives me other than "my object", then let me know. It's like worst of bother worlds: little value and the rest of your java code moves closer to an in-container solution. So testing is a PITA as well. Anyone else feel this way?
  20. No edit?[ Go to top ]

    Words of wisdom here are to proof read you post before hand. Hey, it's Monday and starbucks hasn't kicked in. lol
  21. I agree[ Go to top ]

    If you make your code independent of the framework then you just move the problem into your XML file. The XML file will be dependent on your Java code and if you make changes to your code then you have to remember to change your XML, which is not statically typed. This way of creating programs are bad. For some reason many seems to think that if you program in XML all problems goes away. If you use the annotation strategy it is just as flexible and more straight forward to use a factory.