主持人用匕首注射2

我刚开始使用匕首2,我发现在线数以千计的指导每一个不同的实现,我现在有点困惑。 所以基本上这就是我现在写的:

AppModule.java

@Module public class AppModule { Application mApplication; public AppModule(Application application) { mApplication = application; } @Provides @Singleton Application providesApplication() { return mApplication; } } 

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:

 @Module(includes = DataModule.class) public class PrefsModel { @Provides @Singleton QueryPreferences provideQuery(SharedPreferences prefs) { return new QueryPreferences(prefs); } } 

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

 @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应该实现HomePresenter与“新HomePresenter(networkService)”,但现在我不知道如何使用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); 

Solutions Collecting From Web of "主持人用匕首注射2"

你在混合东西。 要提供您的演示者,您应该切换到以下内容:

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

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

提供接口使用这个构造函数,并依赖于实现

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

这样你就不必自己调用任何构造函数。 而实际上注入演示者…

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

这样你会注入的东西。 请仔细阅读,并尝试了解它。 这将解决你的主要问题,你仍然不能提供同一个模块的同一types的2个主持人(在相同的范围内)

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

这是行不通的。 你不能提供2个同类的对象。 他们是难以区分的。 看看像@Named这样的@Qualifiers如果你确定这是你想要的方式。

如果在构造函数中使用@Inject注释,则不必提供Presenter。 在类的构造函数中使用@Inject注释使该类成为依赖关系图的一部分。 所以,它也可以在需要的时候注入。

另一方面,如果将@Inject注解添加到字段,但不添加到构造函数,则必须提供该类。