Part 7 – Stateful Modules

Links & DependenciesPetrolEngine.javaDieselEngine.javaPetrolEngineModule.javaDieselEngineModule.javaRims.javaTires.javaWheelsModule.javaRemote.javaCar.javaEngine.javaWheels.javaMainActivity.javaCarComponent.java

Dagger 2 dependencies:

github.com/google/dagger

package com.codinginflow.dagger2example.car;

import android.util.Log;

import javax.inject.Inject;

public class PetrolEngine implements Engine {
    private static final String TAG = "Car";

    @Inject
    public PetrolEngine() {

    }

    @Override
    public void start() {
        Log.d(TAG, "Petrol engine started");
    }
}
package com.codinginflow.dagger2example.car;

import android.util.Log;

public class DieselEngine implements Engine {
    private static final String TAG = "Car";

    private int horsePower;

    public DieselEngine(int horsePower) {
        this.horsePower = horsePower;
    }

    @Override
    public void start() {
        Log.d(TAG, "Diesel engine started. Horsepower: " + horsePower);
    }
}
package com.codinginflow.dagger2example.dagger;

import com.codinginflow.dagger2example.car.Engine;
import com.codinginflow.dagger2example.car.PetrolEngine;

import dagger.Binds;
import dagger.Module;

@Module
public abstract class PetrolEngineModule {

    @Binds
    abstract Engine bindEngine(PetrolEngine engine);
}
package com.codinginflow.dagger2example.dagger;

import com.codinginflow.dagger2example.car.DieselEngine;
import com.codinginflow.dagger2example.car.Engine;

import dagger.Module;
import dagger.Provides;

@Module
public class DieselEngineModule {
    private int horsePower;

    public DieselEngineModule(int horsePower) {
        this.horsePower = horsePower;
    }

    @Provides
    Engine provideEngine() {
        return new DieselEngine(horsePower);
    }
}
package com.codinginflow.dagger2example.car;

public class Rims {
    //we don't own this class so we can't annotate it with @Inject
}
package com.codinginflow.dagger2example.car;

import android.util.Log;

public class Tires {
    //we don't own this class so we can't annotate it with @Inject

    private static final String TAG = "Car";

    public void inflate() {
        Log.d(TAG, "Tires inflated");
    }
}
package com.codinginflow.dagger2example.dagger;

import com.codinginflow.dagger2example.car.Rims;
import com.codinginflow.dagger2example.car.Tires;
import com.codinginflow.dagger2example.car.Wheels;

import dagger.Module;
import dagger.Provides;

@Module
public abstract class WheelsModule {

    @Provides
    static Rims provideRims() {
        return new Rims();
    }

    @Provides
    static Tires provideTires() {
        Tires tires = new Tires();
        tires.inflate();
        return tires;
    }

    @Provides
    static Wheels provideWheels(Rims rims, Tires tires) {
        return new Wheels(rims, tires);
    }
}
package com.codinginflow.dagger2example.car;

import android.util.Log;

import javax.inject.Inject;

public class Remote {
    private static final String TAG = "Car";

    @Inject
    public Remote() {

    }

    public void setListener(Car car) {
        Log.d(TAG, "Remote connected");
    }
}
package com.codinginflow.dagger2example.car;

import android.util.Log;

import javax.inject.Inject;

public class Car {
    private static final String TAG = "Car";

    private Engine engine;
    private Wheels wheels;

    @Inject
    public Car(Engine engine, Wheels wheels) {
        this.engine = engine;
        this.wheels = wheels;
    }

    @Inject
    public void enableRemote(Remote remote) {
        remote.setListener(this);
    }

    public void drive() {
        engine.start();
        Log.d(TAG, "driving...");
    }
}
package com.codinginflow.dagger2example.car;

public interface Engine {

    void start();
}
package com.codinginflow.dagger2example.car;

public class Wheels {
    //we don't own this class so we can't annotate it with @Inject

    private Rims rims;
    private Tires tires;

    public Wheels(Rims rims, Tires tires) {
        this.rims = rims;
        this.tires = tires;
    }
}
package com.codinginflow.dagger2example;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.codinginflow.dagger2example.car.Car;
import com.codinginflow.dagger2example.dagger.CarComponent;
import com.codinginflow.dagger2example.dagger.DaggerCarComponent;
import com.codinginflow.dagger2example.dagger.DieselEngineModule;

import javax.inject.Inject;

public class MainActivity extends AppCompatActivity {
    @Inject Car car;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        CarComponent component = DaggerCarComponent.builder()
                .dieselEngineModule(new DieselEngineModule(100))
                .build();

        component.inject(this);

        car.drive();
    }
}
package com.codinginflow.dagger2example.dagger;

import com.codinginflow.dagger2example.MainActivity;
import com.codinginflow.dagger2example.car.Car;

import dagger.Component;

@Component(modules = {WheelsModule.class, DieselEngineModule.class})
public interface CarComponent {

    Car getCar();

    void inject(MainActivity mainActivity);
}