Tests are definitely not the best place to be learning how Guice works.
Specifically, you shouldn't be attempting to inject things into JUnit test
classes (instances of which are created for you by JUnit) and basing your
understanding of Guice on your experience with that, considering that Guice
making instances of classes for you is the very core of how it works, and it
can't do it in that case.

Your understanding of Modules as analogous to Spring bean IDs is not
correct. Modules are units of configuration... they define groups of related
bindings, similar to what you might put in a single Spring XML file. Guice
then autowires by providing @Inject annotated fields, methods and
constructors with instances of the type they require according to the
defined bindings. If you were using the module from your sample code, in an
application, everywhere Guice saw "@Inject public MyClass(Template
template)", for example, it would create an instance of SomeTemplate,
providing it with the Session object, and then pass that SomeTemplate to the
MyClass constructor as its Template.

If you need more than one kind of binding for Template, you use binding
annotations (see
http://code.google.com/p/google-guice/wiki/BindingAnnotations). The
combination of type (i.e. Template) and binding annotation is called a key
and is what determines what should be injected where... that is the analog
to the ID of a bean in Spring.

Also important to note is that in any given application, modules and
Guice.createInjector() should only be called once, at the application entry
point. Some root application object should then be retrieved from the
Injector and used to start the application. When Guice needs to get the
instance of that application object, it will inject its dependencies (and
the dependencies of those objects, etc.) based on the configuration in the
modules.

To extend your initial example, imagine an application like this:

class Application {
  TemplateClient1 client1;
  TemplateClient2 client2;

  @Inject Application(TemplateClient1 client1, TemplateClient2 client2) {
    this.client1 = client1;
    this.client2 = client2;
  }

  void start() { ... }
}

Where TemplateClient1 and TemplateClient2 are two classes with a constructor
like

@Inject TemplateClient1(Template template) { ... }

Then you bootstrap the application:

class Main {
  public static void main(String[] args) {
    Injector injector = Guice.createInjector(new TemplateModule.Builder()
      .withSession(new Session()).buildModule());

    Application app = injector.getInstance(Application.class);
    app.start();
  }
}

Since Application, TemplateClient1 and TemplateClient2 are concrete classes,
we don't even need to write any binding for them. The Application object
retrieved from the injector here will have its client1 and client2 fields,
and those objects will each have an instance of TemplateImpl as their
template, and each of those instances of TemplateImpl will have the Session
object that was bound in the module.

I'd advise working on some simple application like the above to help you
understand how Guice works, and also reading more of the user's guide.

Colin

On Wed, Mar 3, 2010 at 4:29 AM, infinity2heaven <[email protected]>wrote:

> Thanks Eelco, I figured the anonymous inner class accessing an object
> reference, and while fixing it, your suggestion of using
> requestStaticInjection solves my problem.
>
> Dhanji:
> I still don't understand how autowire is "by default" in Guice. In the
> example I mentioned, I have to create n modules for each Class
> referencing template variable. Agreed, the following code
>
> new AbstractModule() {
>        @Override
>        public void configure() {
>                 requestStaticInjection (this);
> }});
>
> would inject the reference in the static instance, but that means I
> have to write the same boilerplate code for every test, ie, every
> class that has @Inject Template template.
>
> @Inject is a Guice annotation and I expect it to be smart to figure
> out (autowire) the binding.
>
> As I understand now, this is not the case.
>
> On Mar 3, 1:02 am, Eelco Hillenius <[email protected]> wrote:
> > > injector = Guice.createInjector(new
> > > TemplateModule.Builder().withSession(new Session()).buildModule(),
> > >   new AbstractModule() {
> > >        @Override
> > >        public void configure() {
> > >                requestInjection(this);
> > >    }});
> >
> > This doesn't work because requestInjection(this) requests injection of
> > your anonymous module
> > and because @BeforeClass can only be used on a static method, so there
> > is no 'this' for your unit test.
> >
> > I think adding a method with @Before and then
> > requestInjection(YourTest.this) should work. Or you could use
> > requestStaticInjection instead. Or, what I would do frankly, don't
> > bother and just get your instance from the injector when you need it.
> >
> > Eelco
>
> --
> 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]<google-guice%[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.

Reply via email to