Does Module support injection? how about injecting android.app.Application?

56 views
Skip to first unread message

Mingfai Ma

unread,
Jun 14, 2013, 8:33:10 AM6/14/13
to tran...@googlegroups.com
hi,

First of all, thanks John for creating this very promising framework.

Let me share some comments first. I'm evaluating Transfuse and want to see if it can replace Dagger in an existing project. Transfuse does much more than Dagger on the Android framework components injection side, but Dagger is evolved from Guice and they do non-Android specific dependency injection very well. One thing I like about Transfuse is, the generated .java code with error just show up in my IDE that I know how it works and can try to troubleshoot any problem. Is Transfuse suppose to be able to replace Dagger (... ultimately)?

The first issue I encountered is, in Dagger, any @Provides method supports injection, and arguments will just be wired from the ObjectGraph. e.g.
   @Provides Dog getDog( PetStore store){
      return store.getPet("dog", 0); //whatever, just make it more realistic :-)
   }
PetStore will be "injected" just like putting it in a @Inject attribute in other class.

I checked the doc (http://androidtransfuse.org/documentation.html#dependency_injection_di) and those examples (e.g. org.androidtransfuse.integrationTest.IntegrationModule) and it doesn't seem to mention such usage. Can we use arguments in @Provides methods and expect the arguments be injected?

Transfuse actually translate every @Provides method to a provider. Should every argument in a @Provides essentially the same as creating a Provider with @Inject attributes? Assume @Inject attribute in Provider will be injected, that shouldn't be the case, right?

Last but not least, for a real case, I want to inject an android.app.Application instance to the @Provides method, like the following:
  @Provides Something getSomething(android.app.Application ctx)

The generated code shows an error and the "app" becomes this.getApplication(). If I replace "android.app.Application ctx" with "android.app.Activity ctx", Transfuse is intelligent enough to change the generated code from "this.getApplication()" to "this", indicate the generated Provider class is somehow viewed as an activity.

May I have some hints about the current status of the module usage before I have to dig into the Transfuse source code? thank you very much 

Regards,
mingfai

John Ericksen

unread,
Jun 14, 2013, 9:13:37 AM6/14/13
to tran...@googlegroups.com
Thanks for your comments Mingfai.

I'm glad you've had success with the generated code showing up in your IDE.  I've had a lot of difficulty with that and haven't been 100% satisfied with the results.

You should be able to inject into providers just as you can with Dagger.  Rather, the arguments of the @Provides methods are provided via Transfuse.  Your PetStore example should work just as you wrote it.

Using Application as an argument in Transfuse should work as well.  I've created a quick demo here:
https://github.com/johncarl81/hello-transfuse
Notably the module @Provides:
https://github.com/johncarl81/hello-transfuse/blob/master/src/main/java/org/androidtransfuse/Module.java
And the injection:
https://github.com/johncarl81/hello-transfuse/blob/master/src/main/java/org/androidtransfuse/HelloAndroid.java

If you're using this via a @Factory, you may need to provide an Application to the Factory:

@Factory
public interface Injector {

    public PetStore getPetstore(Application application);
}

The @Factory feature is probably the closes thing to Dagger's ObjectGraph functionality.

It looks like there is currently a bug with using the @Factory classes statically via the Factories utility and using Module @Provides.  I'll investigate and fix that soon ( https://github.com/johncarl81/transfuse/issues/36)  For now if you want this functionality you will need to inject the @Factory into an @Activity or related object graph.

Transfuse Modules are a bit different than Dagger's as you have probably found out.  Where Dagger uses module instances that you create to build the object graph, Transfuse will instantiate the  @TransfuseModule as a singleton.  Also, in Transfuse, modules are currently lumped into one if you define more than one.

I hope I answered your questions, let me know if you need more details.

Thanks.

John
--
You received this message because you are subscribed to the Google Groups "Transfuse" group.
To unsubscribe from this group and stop receiving emails from it, send an email to transfuse+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

John Ericksen

unread,
Jun 15, 2013, 3:46:24 PM6/15/13
to tran...@googlegroups.com
FYI, the mentioned issue is now resolved.  You can now use teh module @Provides via the Factories utility class like so:

Module:
@TransfuseModule
public class Module {

    @Provides
    @Named("packageName")
    public String getName(Application application){
        return application.getPackageName();
    }
}

Injector @Factory interface:

@Factory
public interface Injector {

    @Named("packageName")
    String getPackageName(Application application);
}

Usage:

Factories.get(Injector.class).getPackageName(application));

This should call the Module @Provides method and return application.getPackageName().  Obviously a contrived example, but I think this has a lot of merit.

John
Reply all
Reply to author
Forward
0 new messages