Dagger 2相互依赖问题

时间:2018-08-17 11:40:28

标签: android dependency-injection dagger-2

在我的应用程序中,我试图为

创建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中使用已经具有Network组件的AppUtil组件之后

  

在将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)

1 个答案:

答案 0 :(得分:1)

因此,一个组件可以一次创建多个依赖关系,这些依赖关系通常按生存期范围分组(Application =整个应用程序生存期,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类,因此出现编译器错误。为了使它起作用,您应该更改NetworkProcessor使其具有一个用@Inject注释的构造函数,就像使用AppUtils一样(第二种选择是在其中创建一个@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,因此可以自己创建接线代码。