【问题标题】:How to inject pojo dependencies using dagger 2?如何使用 dagger 2 注入 pojo 依赖项?
【发布时间】:2016-02-16 21:04:53
【问题描述】:

我有一个简单的 pojo 类:

public class MySimpleClass {

    private List<String> mDependency;

    public MySimpleClass (List<String> dependency) {
        mDependency = dependency;
    }
}

我正在尝试使用 dagger 2 使用依赖注入创建它。现在我有一个简单的模块和组件:

@Module
public class MySimpleClassModule {

    @Provides
    MySimpleClass provideMySimpleClass(List<String> dependency) {
        return new MySimpleClass(dependency);
    }
}

@Component(modules={MySimpleClassModule.class})
public interface MySimpleClassComponent {
}

但我不确定每次需要创建MySimpleClass 的新实例时如何注入List&lt;String&gt; 依赖项。在上述场景中,似乎我实际上需要将List&lt;String&gt; 添加到MySimpleClassModule 的构造函数中,并且每次我需要一个新的MySimpleClass 实例和一个新的List&lt;String&gt; 时都有一个该模块的新实例。那是对的吗?在这种特殊情况下,开销似乎很大。

【问题讨论】:

    标签: java android dagger-2


    【解决方案1】:

    不,不是。

    我假设您在使用 Dagger 时遇到了编译错误,因为从问题中不清楚您是否已经有一个提供此字符串列表的模块。

    要解决这个问题,您可以简单地:

    @Module
    public class MySimpleClassModule {
    
        @Provides
        List<String> provideListDependency() {
            return Arrays.asList("One", "Two");
        }
    
        @Provides
        MySimpleClass provideMySimpleClass(List<String> dependency) {
            return new MySimpleClass(dependency);
        }
    }
    

    如果您认为提供此列表应该是不同模块的一部分,您可以移动它。主要的是,Dagger 在编译期间能够找到如何获取此依赖项。

    如果您不想在 over 中创建此数组,可以将方法标记为 @Singlethon,以便 dagger 将其缓存。

    【讨论】:

      【解决方案2】:

      如果要定义对象的构造函数,最好使用@Inject 构造函数。 Dagger 2 将自动知道如何实例化对象,因此您不需要在模块中使用 @Provides 注释方法。

      public class MySimpleClass {
      
          private List<String> mDependency;
      
          @Inject
          public MySimpleClass (List<String> dependency) {
              mDependency = dependency;
          }
      }
      

      Dagger 将假定构造函数的参数是依赖关系,并尝试从依赖关系图中解析它们。请注意,每个类只能有一个 @Inject 带注释的构造函数!如果您不能自己实例化对象(例如 Android 活动/片段),则需要使用字段注入。

      在您的情况下,似乎没有必要将空列表注入MyClass。您可以在构造函数中实例化列表。但是,当您想将MyClass 注入另一个对象时,它已经在对象图中了。

      【讨论】:

      • 谢谢,但我认为这并不能真正解决问题。在你的方法中,我现在必须声明一种方法来“提供”我的 List&lt;String&gt; 依赖项,比如在模块中。所以每次我需要MySimpleClass 的新实例时,我仍然需要实例化一个新模块。
      • 现在,如果我按照您的建议进行更改,我会收到“错误:没有@Provides-annotated 方法就无法提供 java.util.Collection。”
      • 就像我说的,你真的不需要注入你的列表。只需在您的对象内实例化它。 public class MySimpleClass { private List&lt;String&gt; mDependency; @Inject public MySimpleClass () { mDependency = new ArrayList&lt;&gt;(); } }
      【解决方案3】:
      class A {
          String name;
          @Inject
          A(String name) {
              this.name = name;
          }
      
      
          @Component
          interface AComponent {
              A getA();
              @Component.Builder
              interface Builder {
                  @BindInstance
                  Builder provideName(String name);
                  A build();
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多