【问题标题】:Dagger 2 interdependency issueDagger 2 相互依赖问题
【发布时间】:2019-01-24 10:52:44
【问题描述】:

在我的应用程序中,我正在尝试为

创建Dagger 2 组件
  1. Context(用于不同的类)已经完成了
  2. AppUtil(需要网络检查方法的上下文)需要完成这项工作!

我已经创建了组件并从 Application 类启动。

    public class MyApp extends Application{

      private ContextComponent mContextComponent;
      private AppUtilComponent mAppUtilComponent;
      private NetworkComponent mNetworkComponent;

      @Override
        public void onCreate() {
            super.onCreate();
            mNetworkComponent = createNetworkComponent();
            mContextComponent =  createContextComponent();
            mAppUtilComponent = createAppUtilComponent();
        }

        private AppUtilComponent createAppUtilComponent() {
                return DaggerAppUtilComponent.builder().appUtilModule(new AppUtilModule(this)).build();
        }

        public AppUtilComponent getAppUtilComponent() {
           return mAppUtilComponent;
        }

        private NetworkComponent createNetworkComponent() {
             return DaggerNetworkComponent.builder().networkModule(new NetworkModule()).build();
        }

        public NetworkComponent getNetworkComponent() {
            return mNetworkComponent;
        }

        private ContextComponent createContextComponent() {

            return DaggerContextComponent.builder().contextModule(new ContextModule(this)).build();
        }

        public ContextComponent getContextComponent(){
            return mContextComponent;
        }
    }

ContextModule类如下

@Module
public class ContextModule {

    private Context mContext;

    public ContextModule(Context context){
        mContext = context;
    }

    @Provides
    @Singleton
    Context getContext(){
        return mContext;
    }
}

上下文组件将是

@Singleton
@Component (modules = ContextModule.class)
public interface ContextComponent {

    void inject(AppUtils appUtils);

}

AppUtilModule 就像

@Singleton
@Component (modules = AppUtilModule.class)

public interface AppUtilComponent {

   void inject(SplashActivity splashActivity);
}

有了这个 AppUtilModule 已经修改为

@Module (includes = ContextModule.class)
public class AppUtilModule {

    private AppUtils mAppUtils;
    private Context context;

    @Inject
    public AppUtilModule(Context context) {
        this.context = context;
    }

    @Provides
    public AppUtils getAppUtil(){
        mAppUtils = new AppUtils(context);
        return mAppUtils;
    }
}

现在我的 AppUtils 正在注入上下文,这完全没问题。

public class AppUtils {

    public Context mContext;

    @Inject
    public AppUtils(Context _context){
        mContext = _context;
    }

    public boolean isNetworkConnected(){
     //Using mContext to determine Network
    }
    ... Other Utility methods which will be used throughout my application
}

但是现在我怎样才能使AppUtil 成为一个单独的 Dagger 组件(其中 是否在内部将 Context 作为依赖项)并注入其他类?


编辑 1:在将上下文构造函数注入 AppUtils 并在 SplashActivity 中使用 AppUtil 组件后,该组件已经具有 Network 组件

将 AppUtil 设置为 Dagger 依赖项后,现在 Project 正在提供 编译时错误。在此更改之前,SplashActivity 中的 NetworkProcessor 曾经工作 很好,因为它只是 SplashActivity 的依赖项。我是什么 我错过了/做错了!

public class SplashActivity ....
 {

    @Inject
    public NetworkProcessor mNetworkProcessor;
    .....
    @Inject
    public AppUtils mAppUtils;

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

        MyApp.getInstance().getAppUtilComponent().inject(this);

        MyApp.getInstance().getNetworkComponent().inject(this);
    }

}

错误:

rror: [Dagger/MissingBinding] com.dev.myapp.networking.NetworkProcessor cannot be provided without an @Inject constructor or an @Provides-annotated method.
com.dev.myapp.networking.NetworkProcessor is injected at
com.dev.myapp.ui.activities.landing.SplashActivity.mNetworkProcessor
com.dev.myapp.ui.activities.landing.SplashActivity is injected at
com.dev.myapp.components.AppUtilComponent.inject(com.dev.myapp.ui.activities.landing.SplashActivity)

【问题讨论】:

  • 好的,现在的情况和你编辑之前的情况完全不同......
  • NetworkProcessor 的依赖项是什么?
  • 它以Retrofit为组件,在SplashActivity中使用
  • 你有一个改装匕首组件?或者你在说什么样的组件?
  • 我认为您的 Dagger 设置过于复杂。我制作了一个视频来帮助开发人员使用 Dagger。有些人觉得它很有用,所以也许你可以从那里得到一些想法:youtu.be/cx6pCIbOqtI

标签: android dependency-injection dagger-2


【解决方案1】:

所以一个组件可以一次创建多个依赖项,这些依赖项通常按生命周期范围分组(Application = 整个应用生命周期,Activity = Activity 生命周期)。

因此,如果您的 AppUtils 类与您的 ContextComponent 具有相同的范围,您可以使用它将 AppUtils 注入应该使用它的类中,例如一个活动:

public class MainActivity extens Activity {

    @Inject AppUtils appUtils;

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

        ((MyApp) getApplication()).getContextComponent().inject(this);
    }
}

将 ContextComponent 定义扩展为

@Singleton
@Component (modules = ContextModule.class)
public interface ContextComponent {

    void inject(AppUtils appUtils);

    void inject(MainActivity activity);
}

您需要更改AppUtils 以使用构造函数注入:

public class AppUtils {
    private Context mContext;

    @Inject 
    public AppUtils(Context context){
        this.mContext = context;
    }
}

问题编辑 1 之后

Dagger 不知道如何创建NetworkProcessor-class,因此编译器出错。要使其工作,您应该更改 NetworkProcessor 以拥有一个带有 @Inject 注释的构造函数,就像您对 AppUtils 所做的那样(第二个选项是在 dagger 模块中创建 @Provides 方法,但第一个解决方案更容易)。

您没有提供NetworkProcessor 的源代码,所以我在这里假设它只需要一个Context 作为依赖项。

现在AppUtilsNetworkProcessor 都有一个仅以Context 作为参数的可注入构造函数,Dagger 可以自己创建缺失的链接。

你不需要NetworkComponentAppUtilComponent,只需要一个组件,所以删除它们。同时删除NetworkModuleAppUtilModuleContextComponent 现在足以将所有依赖项注入SplashActivity

public class SplashActivity .... {

    @Inject public NetworkProcessor mNetworkProcessor;
    .....
    @Inject public AppUtils mAppUtils;

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

        MyApp.getInstance().getContextComponent().inject(this);
    }
    //...
}

这是因为 Dagger 可以自己创建接线代码,因为它知道如何实例化 AppUtilsNetworkProcessor

【讨论】:

  • 已经尝试过了。这样做,我已经收到错误。原因==> AppUtils 需要上下文。并且需要在 AppUtils 组件之前创建/处理上下文组件。如果您有任何解决此问题的示例,请更新您的答案
  • 哦,您需要更改AppUtils 才能使用构造函数注入
  • 谢谢,我会试试这个并回复。如果解决了,您将获得支持和正确答案:)
  • 在使用构造函数注入进行更新后,具有先前依赖关系的类本身会在编译时出错。我已经更新了我的问题:(
  • 我的目的是让所有三个模块保持不同。因此,如果一个类只需要第一个组件,则该类可以由第一个组件提供。另一方面,如果某个类需要所有 3 个组件,则可以为该类提供所有三个组件...我将通过您更新的代码。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-07
  • 1970-01-01
  • 1970-01-01
  • 2017-02-26
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
相关资源
最近更新 更多