Dagger2:使用工厂方法代替公共构造函数

时间:2015-08-30 17:21:19

标签: java dependency-injection factory dagger-2

我正在尝试使用公共工厂方法代替Dagger2的公共构造函数。但是想想我在使用Dagger2时缺少一些联系。

当我使用公共构造函数时,我的示例接口/类如下:

interface InterfaceA {
    void foo();
}

class A implements InterfaceA {

    @Inject public A() {}

    @Override
    public void foo() {
        System.out.println("foo");
    }
}

interface InterfaceB {
    void bar();
}

class B implements InterfaceB {

    private final InterfaceA depA;

    @Inject public B(InterfaceA depInstance) {
        depA = depInstance;
    }

    @Override
    public void bar() {
        System.out.println("bar");
        depA.foo();
    }
}

@Module class MyModule {

    @Provides InterfaceA provideA(final Provider<A> provider) {
        return A.create(provider);
    }

    @Provides InterfaceB provideB(B bInstance) {
        return bInstance;
    }
}

@Component(modules=MyModule.class)
interface MyComponent {
    InterfaceA provideInterfaceA();
    InterfaceB provideInterfaceB();
}

上述用法:

public class Test {

    public static void main(String[] args) {
        MyComponent comp = DaggerMyComponent.create();
        InterfaceA a = comp.provideInterfaceA();
        a.foo();
        InterfaceB b = comp.provideInterfaceB();
        b.bar();
    }
}

现在,如果我按如下方式重写A和B类:

class A implements InterfaceA {

    public static A create() {
        return new A();
    }

    private A() {}

    @Override
    public void foo() {
        System.out.println("foo");
    }
}

class B implements InterfaceB {

    public static B create(InterfaceA depA) {
        return new B(depA);
    }

    private final InterfaceA depA;

    private B(InterfaceA depInstance) {
        depA = depInstance;
    }

    @Override
    public void bar() {
        System.out.println("bar");
        depA.foo();
    }
}

我可以将MyModule类重写为:

@Module class MyModule {

    @Provides InterfaceA provideA() {
        return A.create();
    }

    @Provides InterfaceB provideB() {
        return B.create(provideA());
    }
}

但这并没有使用很多Dagger2框架。 看起来我没有编写我的类来正确使用Inject和提供注释。我错过了什么?

1 个答案:

答案 0 :(得分:1)

你实际上非常接近,但你犯了小错误。您应该使用方法参数向provider方法提供实例,否则您将在范围提供者的情况下创建多个实例。如果您愿意,可以使用void inject(Something something);

@Module class MyModule {

    @Provides InterfaceA provideA() {
        return A.create();
    }

    @Provides InterfaceB provideB(Interface A interfaceA) {
        return B.create(interfaceA);
    }
}


@Component(modules=MyModule.class)
interface MyComponent {
    InterfaceA provideInterfaceA();
    InterfaceB provideInterfaceB();

    void inject(Test test);
}

public class Test {
    @Inject
    InterfaceA a;

    @Inject
    InterfaceB b;



    public static void main(String[] args) {
        MyComponent comp = DaggerMyComponent.create();
        comp.inject(this);
        a.foo();
        b.bar();
    }
}