gpt4 book ai didi

java - 使用 Dagger 2 进行 Presenter 注入(inject)

转载 作者:搜寻专家 更新时间:2023-10-30 21:46:40 24 4
gpt4 key购买 nike

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

AppModule.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);
}

所以,我有几个问题对我在线阅读文档来说不清楚:

  • 由于 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);
}

然后我这样修改了presenter的构造函数:

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

然后自动注入(inject) NetworkService。

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

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

最佳答案

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

尽可能使用构造函数注入(inject)。这会让事情变得更容易

public class HomePresenterImpl {

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

}

要提供接口(interface),请使用此构造函数注入(inject)并依赖实现:

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);
}
}

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

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

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

不会工作。您不能提供 2 个同类对象。它们是无法区分的。看看@Qualifiers喜欢 @Named 如果您确定这是您想要的方式。

关于java - 使用 Dagger 2 进行 Presenter 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36838898/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com