I'm trying to decide whether to use Transfuse or Dagger for Android dependency injection. I've never used Transfuse, and have basic knowledge of Dagger. Thanks much.
问题:
回答1:
To start, I am the primary author of Transfuse thus this answer may be a bit slanted in that direction.
Both Transfuse and Dagger handle Dependency Injection / Inversion of Control for Android in similar ways. Both use Annotation Processing at Compile time via JSR269 to generate code the supports the DI/IOC functionality. This allows them to avoid the costly runtime reflection-based analysis typically associated with DI containers found in non-Android Java. Without going into the specifics, Dagger and Transfuse do approach code generation in significantly different ways, which is reflected in the features of the libraries. Also, Transfuse and Dagger both use the common JSR330 annotations (@Inject, Provider, etc). This means they both follow a Guice-style injection scheme.
Here's how you create an object graph in Dagger:
public class DaggerActivity extends Activity {
@Inject Example example;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ObjectGraph.create().inject(this);
//do something else...
}
}
The equivalent code in Transfuse uses its @Factory functionality:
@Factory
public interface Injector {
Example get();
}
public class TransfuseActivity extends Activity {
Example example;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
example = Factories.get(Injector.class).get();
//do something else...
}
}
Transfuse is meant to be used in the following way, however, utilizing POJO components, lifecycle events, etc:
@Activity
public class TransfuseActivity{
@Inject Example example;
@OnCreate public void doSomethingElse(){
//do something else...
}
}
Here's some little differences in the DI engine in Transfuse and Dagger:
- Transfuse supports (as well as it can) cyclic dependencies, Dagger purposefully throws an exception in this case.
- Transfuse satisfies JSR330, Dagger specifically does not. The Dagger developers wanted to err on the side of simplicity, avoiding method injection allowed them to avoid a handful of confusing cases (link).
- Dagger has a reflection based engine for cases where code was not generated. Transfuse does not and requires code to be generated (annotation processor to run) in order to work.
- Transfuse will inject into private fields, constructors, methods (not necessarily recommended because of the reflection overhead). Dagger throws an exception in this case.
- Dagger uses Modules in a very direct way, mirroring the capabilities of Guice. Each time you create an object graph, you are given the option to configure it with a Module class, ie:
ObjectGraph.create(new DripCoffeeModule())
. Transfuse's configuration module is a bit different as it is incorporated into the application at compile time. Each Module in Transfuse is global to the project (this may change in future versions of Transfuse, but it has not been an issue for the use of Transfuse yet). - Singletons in Dagger are per-object-graph where Singletons in Transfuse are global to the application.
The big difference between Dagger and Transfuse is that Dagger focused on being a simple Dependency Injection library, while Transfuse's focus is to "make Android a better API using performance sensitive techniques"
Transfuse supports these capabilities as well as DI:
- POJO Components
- Manifest Management
- Roboguice/Butterknife style injections
- Lightweight event system (@Observes, @OnCreate, etc)
- AOP
I'd recommend that if you're interested, give Transfuse a try. Personally, I'd love to hear about your experience contrasting it with Dagger. We have a mailing list where you can share with the community and pretty through documentation on the website.