Dependency injection – Martin fowler – Injection



Dependency injection – Martin fowler – Injection

0 0


guiceprez

Guice presentation

On Github zabil / guiceprez

Dependency injection

Martin fowler

Guice

Google

3.0

javax.inject (JSR 330)

Injection

Constructor

vs

Setter

Setter based injection

No arg constructor

Setters

Testability

Constructor based injection

public class Greeter{
    Greeter(Output out){
    ...
    }
}

One way of construction

Testability

public class GreeterTest{
    @Test
    public void shouldPrintAGreeting(){
        Greeter greeter = new Greeter(mock(Output.class));
        ...
    }
}

@Inject

public class Greeter{
    @Inject
    Greeter(Output out){
    ...
    }
}

Object Graph

Type safe

vs

XML

XML

Type Safe

Type safe configuration

public interface Output{
    void print(String message);
}
public class Greeter{
    @Inject
    Greeter(Output out){
        out.print("Hello");
    }
}
public class ConsoleOutput implements Output {
    @Override
    void print(String message){
        System.out.println(message);
    }
}

Binding

public class ConsoleModule extends AbstractModule {
    @Override
    protected void configure(){
        bind(Output.class).to(ConsoleOutput.class);
    }
}

Bootstrap

public static void main() {
    Injector injector = Guice.createInjector(new ConsoleModule());

    Greeter greeter = injector.getInstance(Greeter.class);

}

Modules

public class FileOutput extends Output {
    @Override
    void print(String message){
        write(message);
    }
}
public class ConsoleModule extends AbstractModule {
    @Override
    protected void configure(){
        bind(Output.class).to(ConsoleOutput.class);
    }
}
public class FileModule extends AbstractModule {
    @Override
    protected void configure(){
        bind(Output.class).to(FileOutput.class);
    }
}

Bootstrap

public static void main() {

    injectorForConsole = Guice.createInjector(new ConsoleModule());
    injectorForFile = Guice.createInjector(new FileModule());

    consoleGreeter = injectorForConsole.getInstance(Greeter.class);
    fileGreeter = injectorForFile.getInstance(Greeter.class);

}

Legacy

public class DatabaseOutput extends Output {
    DatabaseOutput(DataSource source){
        this.dataSource = dataSource;
    }

    @Override
    void print(String message){
        // do something with dataSource
    }
}

@Provides

public class DatabaseModule extends AbstractModule {
    @Override
    protected void configure(){
        bind(Output.class).to(DatabaseOutput.class);
    }

    @Provides
    DataSource provideDataSource() {
        WhateverDataSource dataSource = new WhateverDataSource();
        dataSource.setJdbcUrl("my/database");
    }
}

Bootstrap

public static void main() {

    injector = Guice.createInjector(new DatabaseModule());

    greeter = injector.getInstance(Greeter.class);
}