使用 Dagger 2 进行 Presenter 注入

2024-01-07

我刚刚开始使用 Dagger 2,我在网上发现了数千个指南,每个指南都有不同的实现,我现在有点困惑。 所以基本上这就是我现在写的:

应用程序模块.java:

@Module
public class AppModule {

 Application mApplication;

 public AppModule(Application application) {
    mApplication = application;
 }

 @Provides
 @Singleton
 Application providesApplication() {
    return mApplication;
 }
}

数据模块.java:

@Module
public class DataModule {

private static final String BASE_URL = "http://beta.fridgewizard.com:9001/api/";

@Provides
@Singleton
NetworkService provideNetworkService() {
    return new NetworkService(BASE_URL);
}

@Provides
@Singleton
SharedPreferences provideSharedPreferences(Application app) {
    return PreferenceManager.getDefaultSharedPreferences(app);
}
}

PrefsModel.java:

@Module(includes = DataModule.class)
public class PrefsModel {

@Provides
@Singleton
QueryPreferences provideQuery(SharedPreferences prefs) {
    return new QueryPreferences(prefs);
}
}

AppComponent.java(我公开 QueryPreferences 对象,因为我在演示者中需要它,希望这种方式是正确的):

@Singleton
@Component(modules = {AppModule.class, DataModule.class, PrefsModel.class})
public interface AppComponent {

    void inject(HomeFragment homeFragment);

    QueryPreferences preferences();
    NetworkService networkService();
}

然后我有 FwApplication.java:

public class FwApplication extends Application {

private static final String TAG = "FwApplication";

private NetworkService mNetworkService;

private AppComponent mDataComponent;

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

       buildComponentAndInject();
    }

    public static AppComponent component(Context context) {
      return ((FwApplication)   context.getApplicationContext()).mDataComponent;
    }

    public void buildComponentAndInject() {
       mDataComponent = DaggerComponentInitializer.init(this);
    }

    public static final class DaggerComponentInitializer {
      public static AppComponent init(FwApplication app) {
        return DaggerAppComponent.builder()
                .appModule(new AppModule(app))
                .dataModule(new DataModule())
                .build();
    }
   }
}

最后我为演示者添加了另一个模块:

@Module
public class PresenterModule {

   @Provides
   Presenter<FwView> provideHomePresenter(NetworkService networkService) {
      return new HomePresenterImpl(networkService);
   }

   @Provides
   Presenter<FwView> provideSearchPresenter(NetworkService networkService) {
      return new SearchPresenterImpl(networkService);
   }

}

以及以下组件(它返回错误,因为我无法在此处添加范围依赖项):

@Component(dependencies = AppComponent.class, modules = PresenterModule.class)
public interface PresenterComponent {

    void inject(HomePresenterImpl presenter);
}

因此,我在阅读在线文档时有几个不清楚的问题:

  • 由于演示组件依赖于 AppComponent 中定义的单例 NetworkService,因此如何修复演示组件中的错误?
  • 我有一个 HomeFragment 应该使用“new HomePresenter(networkService)”实现 HomePresenter,但现在我不知道如何使用定义的 DI

编辑 - 修复:

HomeFragment.java:

public class HomeFragment extends Fragment {

private static final String TAG = "FW.HomeFragment";


@Inject
HomePresenterImpl mHomePresenter;

public static HomeFragment newInstance() {
    return new HomeFragment();
}

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

    FwApplication.component(getActivity()).inject(this);
}

然后我这样修改了演示者构造函数:

@Inject
public HomePresenterImpl(NetworkService networkService) {
    mNetworkService = networkService;
    mInteractor = new InteractorImpl(mNetworkService);
}

然后NetworkService会自动注入。

我想知道这种方式是否正确,因为我必须调用我拥有的每个片段,这些片段需要一个以与上面的代码相同的方式构建的演示者:

FwApplication.component(getActivity()).inject(this);

你把事情搞混了。要提供演示者,您应该切换到如下内容:

如果可能,请使用构造函数注入。这会让事情变得更容易

public class HomePresenterImpl {

    @Inject
    public HomePresenterImpl(NetworkService networkService) {
        // ...
    }

}

要提供接口,请使用此构造函数注入并depend关于实施:

Presenter<FwView> provideHomePresenter(HomePresenterImpl homePresenter) {
    return homePresenter;
}

这样您就不必自己调用任何构造函数。而实际上inject主持人...

public class MyFragment extends Fragment {

    @Inject
    Presenter<FwView> mHomePresenter;

    public void onCreate(Bundle xxx) {
        // simplified. Add your modules / Singleton component
        PresenterComponent component = DaggerPresenterComponent.create().inject(this);
    }
}

这样你就可以注入东西了。请仔细阅读本文并尝试理解它。这将解决您的主要问题,您仍然无法从同一模块(同一范围内)提供 2 个相同类型的演示者

// DON'T
@Provides
Presenter<FwView> provideHomePresenter(NetworkService networkService) { /**/ }

@Provides
Presenter<FwView> provideSearchPresenter(NetworkService networkService) { /**/ }

This will not工作。您不能提供 2 个相同类型的对象。它们是无法区分的。看一下@Qualifiers http://google.github.io/dagger/users-guide.html#qualifiers like @Named如果您确定这是您想要走的路。

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

使用 Dagger 2 进行 Presenter 注入 的相关文章

随机推荐