Reputation: 6389
simple example of using dagger2
UPDATED
I have a Motor class that have Computer and waterpump class. I write them like this by why sub injected parts in Motor is null?
this is my motor class with startEngin method that check computer and waterPump to start.
public class Motor {
@Inject
public Computer computer;
@Inject
public WaterPump waterPump;
public Motor(){
}
// here computer and waterPump are null and not injected
public boolean startEngin(){
if(computer!=null && waterPump!=null){
return true;
}else{
return false;
}
}
}
and this is Computer class that have model name and voltage:
public class Computer {
private int vultage;
private String model;
public Computer(String model ,int vultage){
this.model=model;
this.vultage = vultage;
}
}
and this is WaterPump:
public class WaterPump {
private String name;
public WaterPump(String name){
this.name = name;
}
}
this is my Module:
@Module
public class MotorModule {
Context context;
String motoName;
String computerName;
String waterPupName;
int voltage;
public MotorModule(Context context, String computerName, String waterPupName, int voltage) {
this.context = context;
this.waterPupName = waterPupName;
this.computerName = computerName;
this.voltage = voltage;
}
@Provides
@Singleton
Motor provideMotor() {
return new Motor();
}
@Provides
@Singleton
Computer provideComputer() {
return new Computer(computerName, voltage);
}
@Provides
@Singleton
WaterPump provideWaterPump() {
return new WaterPump(waterPupName);
}
@Provides
@Singleton
Context provideContext() {
return this.context;
}
}
and this is my component class, I know that there is no need to getMotor method.
@Singleton
@Component(modules = {MotorModule.class})
public interface MotorComponent {
// Motor getMotor();
void inject(MainActivity activty);
and here in activity injected motor is null:
public class MainActivity extends AppCompatActivity {
@Inject
public Motor motor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMotorComponent.builder().motorModule(new MotorModule
(this, "mahdi'PC", "my " +
"Water pump", 12)).build().inject(this);
if (motor.startEngin()) {
Toast.makeText(this, "it is started", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "motor is not provided", Toast.LENGTH_SHORT).show();
}
}
}
}
Upvotes: 0
Views: 1343
Reputation: 753
Everything looks OK to me, except for Motor class itself. You annotated two fields with @Inject (so Dagger now knows that it can inject stuff there), but you never actually request Dagger to 'fill' those variables with data. You should explicitly request filling those data somewhere in your code. 1 way to do it is through 'constructor injection', so thats how your constructor should look like
public Motor(Computer computer, WaterPump waterPump) {
this.computer = computer;
this.waterPump = waterPump;
}
...and in module:
@Provides
@Singleton
Motor provideMotor(Computer computer, Waterpump waterpump) {
return new Motor(computer, waterpump);
}
OR you could call dagger instance from your Motor's consctructor and do something like:
myDaggerInstance.inject(this);
and remember to annotate constructor for Motor with @Inject annotation.
Using either way, you explicitly told Dagger to fulfill those dependencies at some point in time, so they won't be null anymore. Cheers!
Upvotes: 2
Reputation: 81539
@Provides
@Singleton
Motor provideMotor() {
return new Motor();
}
And
public class Motor {
@Inject
public Computer computer;
@Inject
public WaterPump waterPump;
public Motor(){
}
Should be one of the following:
1.)
@Singleton
public class Motor {
@Inject
public Computer computer;
@Inject
public WaterPump waterPump;
@Inject
public Motor() {
}
And
public MotorModule(Context context, String computerName, String waterPupName, int voltage) {
this.context = context;
this.waterPupName = waterPupName;
this.computerName = computerName;
this.voltage = voltage;
}
//@Provides
//@Singleton
//Motor provideMotor() {
// return new Motor();
//}
Or
2.)
public class Motor {
public Computer computer;
public WaterPump waterPump;
public Motor(Computer computer, WaterPump waterPump) {
this.computer = computer;
this.waterPump = waterPump;
}
And
@Provides
@Singleton
Motor provideMotor(Computer computer, WaterPump waterPump) {
return new Motor(computer, waterPump);
}
Upvotes: 1
Reputation: 3282
You need to save reference to MotorComponent instance and use it to inject into Activtiy and Motor classes. Add void inject(Motor m) into you component, and call component.inject(myMotor), or use constructor injection on Motor class instead.
public class Motor {
Computer computer;
WaterPump waterPump;
public Motor( Computer computer, WaterPump waterPump){
this.computer = computer;
this.waterPump = waterPump;
}
// here computer and waterPump are null and not injected
public boolean startEngin(){
if(computer!=null && waterPump!=null){
return true;
}else{
return false;
}
}
}
/** Add method, providing Motor class instance - it will use another
.provide() methods from this component to get computer and waterpump objects
(Costtructor injection)
*/
/**
* Arguments is provided by DI
* @param computer
* @param waterPump
* @return
*/
@Provides
@Singleton
Motor provideMotors(Computer computer, WaterPump waterPump) {
Motor motor = new Motor(computer, waterPump);
return motor
}
/** Store reference to your component (better do it in Application) */
MotorComponent component = DaggerMotorComponent.builder().motorModule(new MotorModule
(this, "mahdi'PC", "my " +
"Water pump", 12)).build();
// inject into Activity
componen.inhject(this);
Upvotes: 1