Dagger2: использование фабричных методов вместо публичных конструкторов

Я пытаюсь использовать общедоступные фабричные методы вместо общедоступных конструкторов с 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 ответ

Вы на самом деле довольно близки, хотя вы делаете небольшие ошибки. Вы должны предоставить экземпляр методу провайдера, используя параметр метода, иначе вы бы создали несколько экземпляров в случае провайдера с областью действия. И вы можете использовать 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();
    }
}
Другие вопросы по тегам