问题描述
我刚刚开始使用Dagger 2,我在网上找到了数千个指南,每个指南都有不同的实现,现在我有点困惑。
所以基本上这就是我现在写的:
I just started using Dagger 2 and I found online thousands guides each one with a different implementation and I'm a bit confused now.So basically this is what I wrote at the moment:
AppModule.java:
AppModule.java:
@Module
public class AppModule {
Application mApplication;
public AppModule(Application application) {
mApplication = application;
}
@Provides
@Singleton
Application providesApplication() {
return mApplication;
}
}
DataModule.java:
DataModule.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:
PrefsModel.java:
@Module(includes = DataModule.class)
public class PrefsModel {
@Provides
@Singleton
QueryPreferences provideQuery(SharedPreferences prefs) {
return new QueryPreferences(prefs);
}
}
AppComponent.java(我暴露了QueryPreferences对象,因为我需要在演示者中使用它,希望以这种方式正确):
AppComponent.java (I'm exposing QueryPreferences object since I need it in a presenter, hopefully is correct in this way):
@Singleton
@Component(modules = {AppModule.class, DataModule.class, PrefsModel.class})
public interface AppComponent {
void inject(HomeFragment homeFragment);
QueryPreferences preferences();
NetworkService networkService();
}
然后我有FwApplication.java:
Then I have the 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();
}
}
}
最后我添加了另一个模块演示者:
Finally I added another module for the presenters:
@Module
public class PresenterModule {
@Provides
Presenter<FwView> provideHomePresenter(NetworkService networkService) {
return new HomePresenterImpl(networkService);
}
@Provides
Presenter<FwView> provideSearchPresenter(NetworkService networkService) {
return new SearchPresenterImpl(networkService);
}
}
以下组件(返回错误,因为我无法在此处添加作用域依赖项):
And the following component (which returns error because I cannot add a scoped dependencies here):
@Component(dependencies = AppComponent.class, modules = PresenterModule.class)
public interface PresenterComponent {
void inject(HomePresenterImpl presenter);
}
所以,我几乎没有什么问题不清楚我在线阅读文档:
So, I have few questions that are not clear for me reading the documentation online:
- 如何修复presenter组件中的错误,因为它依赖于NetworkService,这是AppComponent中定义的单例?
- 我有一个HomeFragment应该用new HomePresenter(networkService)实现HomePresenter但现在我不知道如何使用DI定义的
编辑 - 修正:
HomeFragment.java:
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构造函数:
Then I modified the presenter constructor in this way:
@Inject
public HomePresenterImpl(NetworkService networkService) {
mNetworkService = networkService;
mInteractor = new InteractorImpl(mNetworkService);
}
然后自动注入NetworkService。
Then NetworkService is injected automatically.
我想知道它是否以这种方式是正确的,因为我必须调用我所拥有的每个片段需要一个演示者,其构造方式与上面代码相同:
I was wondering if it is correct in this way since I have to call for every fragment I have that needs a presenter constructed in the same way as the one above the following code:
FwApplication.component(getActivity()).inject(this);
推荐答案
你正在混淆东西。要提供演示者,您应该切换到以下内容:
You are mixing thing up. To provide your presenter, you should switch to something like the following:
尽可能使用构造函数注入。它会让事情变得更容易
public class HomePresenterImpl {
@Inject
public HomePresenterImpl(NetworkService networkService) {
// ...
}
}
提供接口使用此构造函数injecetion和依赖实现
To provide the interface use this constructor injecetion and depend on the implementation
Presenter<FwView> provideHomePresenter(HomePresenterImpl homePresenter) {
return homePresenter;
}
这样您就不必亲自调用任何构造函数。实际上注入演示者...
This way you don't have to call any constructors yourself. And to actually inject the presenter...
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个演示者
This way you will inject the things. Please read this carefully and try to understand it. This will fix your major problems, you still can not provide 2 presenters of the same type from the same module (in the same scope)
// DON'T
@Provides
Presenter<FwView> provideHomePresenter(NetworkService networkService) { /**/ }
@Provides
Presenter<FwView> provideSearchPresenter(NetworkService networkService) { /**/ }
此不会工作。您不能提供2个相同类型的对象。它们难以区分。请查看如 @Named
,如果您确定这是您想要的方式。
This will not work. You can not provide 2 objects of the same kind. They are indistinguishable. Have a look at @Qualifiers
like @Named
if you are sure this is the way you want to go.
这篇关于主持人注射Dagger 2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!