【问题标题】:Dagger2: Using factory methods in place of public constructorsDagger2:使用工厂方法代替公共构造函数
【发布时间】:2015-08-30 17:21:18
【问题描述】:

我正在尝试使用公共工厂方法代替 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 和 Provides 注释。我错过了什么?

【问题讨论】:

  • 确保您有意使用无范围的提供者方法和无范围的组件;每个注入调用都会创建一个新实例。

标签: java dependency-injection factory dagger-2


【解决方案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();
    }
}

【讨论】:

  • 确保您有意使用无范围的提供者方法和无范围的组件;每个注入调用都会创建一个新实例。要提供范围,请将 @Singleton 放在您的组件上,并放在您想要设置范围的 @Provides 方法上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-12
  • 1970-01-01
  • 2011-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多