why and how
We don't need it
the objects are given their dependencies at creation time by some external entity that coordinates each object in the system. In other words, dependencies are injected into objects
Spring in action 2 Craig Walls
Goal
the object finds the objects it depends on by itself and then calls them
an external object provides these dependencies when another object needs them for it's creation
do we need it... ?
Java Specification Requests
Cucumber
Typically implemented by an injector
Compared to injecting T directly, injecting Provider<T> enables:
Example
class Car {
@Inject Car(Provider<Seat> seatProvider) {
Seat driver = seatProvider.get();
Seat passenger = seatProvider.get();
...
}
}
get()
Provides a fully-constructed and injected instance of T.
A scope annotation applies to a class containing an injectable constructor, and governs how the injector reuses instances of the type
By default, if no scope annotation is present, the injector creates an instance (by injecting the type's constructor), uses the instance for one injection, and then forgets it.
The implementation of the scope itself is left up to the injector
Annotating scope annotations with @Scope helps the injector detect the case where a programmer used the scope annotation on a class but forgot to configure the scope in the injector. A conservative injector would generate an error rather than not apply a scope.
@Scope @Retention(RetentionPolicy.RUNTIME) public @interface RequestScoped {}
@RequestScoped
@Component(modules = { ... })
public interface CoffeeComponent {
CoffeeMaker maker();
}
usage:
declaration:
@Module and @Provides: mechanism for providing dependencies
@Inject: mechanism for requesting dependencies
@Component: bridge between modules and injectors
@Module public class NetModule {
@Provides @Singleton TSHttpClient provideHttpClient() { return new HttpClient(...); }
}
@Module
public class LibraryModule {
@Provides
@Singleton
List<Specialties> provideSpecialties(TSHttpClient httpClient) {
//httpClient fetch
return specialties;
}
}
@Inject annotation
@Singleton
class LibraryUsecase {
private final LibraryModule libModule;
@Inject
public LibraryUsecase(LibraryModule libModule) {
this.libModule = libModule;
}
Available for downstream injection
class LibraryActivity extends Activity {
@Inject LibraryModule libModule;
/..
}
class LibraryUsecase {
/..
private void enableStreaming(Streaming streaming){
streaming.subscribe(this);
}
/..
}
Components
@Singleton //modules are singletons
@Component(modules {
NetModule.class, LibraryModule.class })
public interface LibraryComponent {
private final LibraryModule libModule;
}
public class MyApp extends Application {
private NetComponent mNetComponent;
@Override
public void onCreate() {
super.onCreate();
mNetComponent = DaggerNetComponent.builder()
// list of modules that are part of this
//component need to be created here too
.appModule(new AppModule(this))
.netModule(new NetModule(
"https://api.github.com"))
.build();
}
}