简体   繁体   English

使用 Dagger2 的项目结构

[英]Project structure with Dagger2

I'm learning how to use Dagger2 and MVP , so i created project, contains one main activity with viewPager and two fragments.我正在学习如何使用Dagger2MVP ,所以我创建了一个项目,其中包含一个带有viewPager主要活动和两个片段。

Code is working, but i'm think i do something wrong when i create my Dagger classes.代码正在运行,但我认为我在创建 Dagger 类时做错了什么。 I think if i contunue, a create a monster =)我想如果我继续,就会创造一个怪物 =)

I'm asking you help to comment my code architecture, associated with Dagger2.我请你帮忙评论我的代码架构,与 Dagger2 相关。 Maybe this question should be on CodeReview: if so, i del and move it.也许这个问题应该在 CodeReview 上:如果是这样,我删除并移动它。

Ok, i show it step by step.好的,我一步一步展示它。 Main suspicions of bad code on step 3.主要怀疑步骤 3 中的错误代码。

At the first, main activity called HomeActivity , and fragment(i show one) called HomePacksFragment .首先,主要活动称为HomeActivity ,片段(我展示一个)称为HomePacksFragment App about animals, and fragment show packs of them, it's why it called so.关于动物的应用程序,以及它们的片段展示包,这就是它这么叫的原因。

1) I have two modules: PresentersModule , provide presenters for HomeActivity and HomePacksFragment : 1)我有两个模块: PresentersModule ,为HomeActivityHomePacksFragment提供演示HomePacksFragment

@Module
public class PresentersModule {
    @Provides
    HomePresenter provideHomePresenter(AnimalDatabase animalDatabase) {
        return new HomePresenter(animalDatabase);
    }

    @Provides
    HomePacksFragmentPresenter provideHomePacksFragmentPresenter(AnimalDatabase animalDatabase) {
        return new HomePacksFragmentPresenter(animalDatabase);
    }
}

and RoomModule prodive access to database and DAO:RoomModule提供对数据库和 DAO 的访问:

@Module
public class RoomModule {
    private AnimalDatabase db;

    public RoomModule(Application mApplication) {
        db = Room.databaseBuilder(mApplication,
                AnimalDatabase.class, AnimalDatabase.DATABASE_NAME)
                .allowMainThreadQueries()
                .fallbackToDestructiveMigration()
                .build();
    }

    @Singleton
    @Provides
    AnimalDatabase providesRoomDatabase() {
        return db;
    }

    @Singleton
    @Provides
    DAO providesProductDao(AnimalDatabase db) {
        return db.daoAccess();
    }
}

2) Then i have component AppComponent who knows all my modules and can inject dependences in concrete view: 2)然后我有组件AppComponent ,它知道我所有的模块并且可以在具体视图中注入依赖项:

@Singleton
@Component(modules = {PresentersModule.class, RoomModule.class})
public interface AppComponent {
    void injectsHomeActivity(HomeActivity homeActivity);
    void injectsHomePacksFragment(HomePacksFragment homePacksFragment);

    DAO animalDao();
    AnimalDatabase animalDatabase();
}

3) Then i have class AnimalsLibraryApp extended Application , and this is the place i make wrong in my opinion. 3)然后我有类AnimalsLibraryApp扩展Application ,这是我认为错误的地方。

public class AnimalsLibraryApp extends Application {
    private static AnimalsLibraryApp instance;
    private static AppComponent homeActivityComponent;
    private static AppComponent homeFragmentPacksComponent;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;

        if (BuildConfig.DEBUG) {
            Timber.plant(new Timber.DebugTree());
        }
        createHomeActivityComponent();
        createHomePacksComponent();
    }

    public static AnimalsLibraryApp getInstance() {
        return instance;
    }

    public static AppComponent getHomeActivityComponent() {
        return homeActivityComponent;
    }

    public static AppComponent getHomeFragmentPacksComponent() {
        return homeFragmentPacksComponent;
    }

    private void createHomeActivityComponent() {
        homeActivityComponent = DaggerAppComponent.builder()
                .presentersModule(new PresentersModule())
                .roomModule(new RoomModule(instance))
                .build();
    }

    private void createHomePacksComponent() {
        homeFragmentPacksComponent = DaggerAppComponent.builder()
                .presentersModule(new PresentersModule())
                .roomModule(new RoomModule(instance))
                .build();
    }
}

Idea of this class was provide singletons of AppComponent.这个类的想法是提供 AppComponent 的单例。 Technicaly it works, but what if i have 10 or 20 views?从技术上讲它有效,但如果我有 10 或 20 次观看怎么办? Class, extended Application is basic class, it will not contain only AppComponent create logic, so much more will be here.类,扩展的Application是基础类,它不会只包含AppComponent创建逻辑,这里还有很多。 Do i write it correct?我写的对吗?

4) It's end. 4) 结束了。 I create my HomeActivity and inject dependences with simple(is't it?) line.我创建了我的HomeActivity并使用简单的(不是吗?)行注入依赖项。

public class HomeActivity extends AppCompatActivity implements HomeContract.View {
    @Inject
    HomePresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        AnimalsLibraryApp.getHomeActivityComponent().injectsHomeActivity(this);

        presenter.attachView(this);
        presenter.viewIsReady();

        DatabaseUtils.copyDatabase(this, AnimalDatabase.DATABASE_NAME);

        ViewPager viewPager = findViewById(R.id.pager);

        HomeMenuAdapter myPagerAdapter = new HomeMenuAdapter(getSupportFragmentManager());
        viewPager.setAdapter(myPagerAdapter);
        TabLayout tabLayout = findViewById(R.id.tablayout);
        tabLayout.setupWithViewPager(viewPager);

        tabLayout.getTabAt(0).setIcon(R.drawable.help);
        tabLayout.getTabAt(1).setIcon(R.drawable.help);
    }
}

I do right things or i must to change something until it's not too late?我做正确的事情还是我必须改变一些事情直到为时已晚?

UPD:更新:

Ok, i google to simple Dagger 2 examples and found this App class version:好的,我用谷歌搜索了简单的 Dagger 2 示例并找到了这个App类版本:

public class MyApp extends Application {
    private static MyApp app;
    private AppModule appModule;
    private BasicComponent basicComponent;

    @Override
    public void onCreate() {
        super.onCreate();
        app = this;

        appModule = new AppModule(this);
        basicComponent = DaggerBasicComponent.builder()
                .appModule(appModule)
                .build();
    }

    public static MyApp app() {
        return app;
    }

    public AppModule appModule() {
        return appModule;
    }

    public BasicComponent basicComponent() {
        return basicComponent;
    }

It's look like better and cleaner that my, but i have a question.它看起来比我的更好更干净,但我有一个问题。 In this example we always retutn basicComponent, so it means that it must included all modules?在这个例子中我们总是返回basicComponent,所以它意味着它必须包含所有模块? It's normal practice to create "god" component?创建“上帝”组件是正常做法吗? =) =)

If i have 3 modules, i need to write(for my example):如果我有 3 个模块,我需要编写(以我的示例为例):

appComponent = DaggerAppComponent
                .builder()
                .appModule(appModule)
                .presentersModule(new PresentersModule())
                .roomModule(new RoomModule(this))
                .build();

According to my idea and the reference as you said you are using AnimalsLibraryApp in a bad way.根据我的想法和您所说的参考资料,您正在以一种糟糕的方式使用 AnimalsLibraryApp。 In the application class, you just need to declare one dagger component then in every view, you will inject the module with that component in the view.在应用程序类中,您只需要声明一个 dagger 组件,然后在每个视图中,您将在视图中注入具有该组件的模块。 If you google a dagger2 sample and check the class that extended the application you will understand.如果您用谷歌搜索 dagger2 示例并检查扩展应用程序的类,您就会明白。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM