Dagger - 嵌套注入,是否需要调用inject()?

2024-02-21

我是 Dagger 的新手,一开始我遇到了一些问题。到目前为止,我的项目结构很简单。我的注入模块:

@Module(
    injects = {GameBoardFragment.class, GameManager.class},
    complete = false,
    library = true
)

public class GameObjectsProviderModule {
private final Application mApplication;

public GameObjectsProviderModule(Application application){
    this.mApplication = application;
}

@Provides
@Singleton
public GameManager provideGameManager(){
    return new GameManager();
}

@Provides
public Board getBoard(){
    return new Board();
}

@Provides @Singleton @ForApplication Context provideAppContext() {
    return mApplication;
}

我的简化自定义应用程序类如下所示:

public class MyApp extends Application {
private static ObjectGraph mApplicationGraph;

@Override public void onCreate() {
    super.onCreate();

    mApplicationGraph = ObjectGraph.create(new GameObjectsProviderModule(this));
}

public static ObjectGraph getObjectGraph(){
    return mApplicationGraph;
}
}

现在,我的片段看起来像这样:

public class GameBoardFragment extends Fragment {

@Inject
GameManager mGameManager;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    MyApp.getObjectGraph().inject(this);

    View root = inflater.inflate(R.layout.fragment_game_board, container, false);
    findViews(root);
    confViews();

    return root;
}
}

最后是我的 GameManager 类

public class GameManager  {

    @Inject Board mBoard;

    public GameManager(){
        MyApp.getObjectGraph().inject(this);
    }
}

安迪嘿,它有效!伟大的。但我的问题是,如果我注释掉这一行,为什么它不起作用:

MyApp.getObjectGraph().inject(this);

我们是否总是显式调用inject()函数来使所有必要的注入发生在嵌套对象中? 看起来不是,如咖啡机示例所示:

https://github.com/square/dagger/tree/master/examples/simple/src/main/java/coffee https://github.com/square/dagger/tree/master/examples/simple/src/main/java/coffee

为什么我必须在 GameManager 类中调用ject() 才能使其正常工作?


Edit:

构造函数注入方法工作得很好。

但为了将来的使用,我尝试运行现场注入,但到目前为止我还没有成功。

我注释掉了模块中的两个 @Provide 方法,并使我的 GameManager 看起来像这样:

@Singleton
public class GameManager  {

@Inject Board mBoard;

@Inject
  public GameManager(){
}
}

和董事会:

public class Board {

  @Inject
  public Board() {
  }
}

但是 mBoard 不会被实例化。我会尝试更多,我想我会找到正确的解决方案。


您应该使用构造函数注入(例如热虹吸管 https://github.com/square/dagger/blob/master/examples/simple/src/main/java/coffee/Thermosiphon.java),除非必要,否则避免现场注入。例如,让你的GameManagerBoard作为构造函数参数:

@Singleton
public class GameManager  {

  private final Board mBoard;

  @Inject
  public GameManager(final Board board){
      mBoard = board;
  }
}

Dagger 将使用这个构造函数来创建一个实例GameManager(因此@Inject注释),并注意它需要一个Board实例。使用ObjectGraph,它将创建一个Board首先,并使用该实例来创建GameManager。您可以删除@Provides GameManager方法,如果你这样做的话。

就你而言,你有一个@Provides Board模块中的方法。如果您添加一个@Inject注释到你的Board构造函数,您可以从模块中删除此提供方法:

public class Board {

  @Inject
  public Board() {
  }
}

如果你不想使用构造函数注入,问题是你告诉 Dagger 你想创建你的GameManager实例化你自己(因为你有@Provides GameManager方法)。如果您删除此方法,并让 Dagger 像上面一样为您创建它,但没有Board构造函数中的参数,Dagger 也会注意到@Inject Board场并注入它。


最后一句话。去除library = true and complete = false声明!在此示例中,这些根本不是必需的。仅当您真正知道自己在做什么时才添加它们。如果没有它们,Dagger 将创建编译时错误来通知您出现问题。如果你确实包含它们,你就是在告诉 Dagger“嘿,我知道我在做什么,别担心,这都是正确的”,但事实上并非如此。


Edit

引用自 Dagger1 网站:

如果你的类有@Inject注解的字段但没有@Inject注解的字段 构造函数,Dagger 将使用无参构造函数(如果存在)。 缺少 @Inject 注解的类无法由 Dagger 构建。

我不经常使用这种方法,所以我可能是错的。我认为这意味着你应该删除@Inject来自构造函数的注释,如下所示:

@Singleton
public class GameManager  {

  @Inject Board mBoard;

  public GameManager(){ // Or remove the constructor entirely since it's empty
  }
}

由于有一个@Inject上的注释Board字段,Dagger 会知道使用无参构造函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Dagger - 嵌套注入,是否需要调用inject()? 的相关文章

随机推荐