3

I'm writing an API that uses Guice for all its DI and want to hide all Guice "stuff" from the API developers. I have the following:

public class MyAppModule extends AbstractModule { @Override public void configure(Binder binder) { // Omitted for brevity... // For instance, binds interface type Animal to impl type Dog, etc. } } public class MyInjector { public abstract<?> inject(Class<?> clazz) { MyAppModule module = new MyAppModule(); Injector injector = Guice.createInjector(module); return injector.getInstance(clazz); } } // So that API developers can just use Animal references and Guice will // automatically inject instances of Dog MyInjector injector = new MyInjector(); Animal animal = injector.inject(Animal.class); // <-- Guice returns a Dog instance 

The problem is with my MyInjector#inject(Class<?>) method. Written the way it is, I'm getting a compiler error:

Multiple markers at this line - Return type for the method is missing - Syntax error on token "?", invalid TypeParameter 

According to the Guice docs, Injector#getInstance returns an abstract<T>. If possible I'd like to avoid generics as well as explicit typecasting, to make things simpler for my API developers. Do I have any options here? If so, what are they? If not, why? Thanks in advance.

2
  • +1 for Avirams answer. One more remark: creating the injector might be expensive, so you should call createInjector in the constructor of MyInjector and just use the instance in the inject() method. Commented Dec 25, 2012 at 10:15
  • in addition: I do not understand what you try to achieve ... Handling DI and injectors is not difficult but also non-trivial. Consider if you really want API-users create injectors via "new". You might end up with many injectors and thus have no guaranty that scopes like Singleton really work. Since the API users will have to use @Inject anyway for this to work, why not simply write a "getting started" that links to guice and explain them why and how to create injectors ... Commented Dec 25, 2012 at 10:18

2 Answers 2

5

Don't use the wildcard ? use something like T

Also, an abstract method can't have an implementation so you need to remove it (you are overriding the method)

public <T> T inject(Class<T> clazz) { MyAppModule module = new MyAppModule(); Injector injector = Guice.createInjector(module); return injector.getInstance(clazz); } 
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @Aviram Segal - you nailed it.
2

You should use something like:

public <T> T inject(Class<T> clazz); 

When using T instead of ? you can return a object of type T

By the way this is the same what Injector does:

public abstract T getInstance (Class<T> type) 

Note: In your code you try to implement an abstract method. You should remove the abstract keyword or you will get a syntax error. Abstract methods cannot contain an implementation (this is done in sub classes).

2 Comments

Thanks @micha (+1) - however implementing these changes yields new errors: Multiple markers at this line -The abstract method inject in type Injector can only be defined by an abstract class -Abstract methods do not specify a body...
This is because your method is abstract. When using abstract you cannot provide an implementation for this method (this has to be done in subclasses). In your case you can just remove the abstract and it should work.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.