Структура проекта с Dagger2 - PullRequest
0 голосов
/ 02 марта 2019

Я учусь использовать Dagger2 и MVP , поэтому я создал проект, содержащий одно основное действие с viewPager и два фрагмента.

Кодработает, но я думаю, что делаю что-то не так, когда создаю свои классы Dagger.Я думаю, если я продолжу, создать монстра =)

Я прошу вас помочь прокомментировать мою архитектуру кода, связанную с Dagger2.Может быть, этот вопрос должен быть на CodeReview: если так, я делаю и переместить его.

Хорошо, я покажу это шаг за шагом.Основные подозрения на плохой код на шаге 3.

На первом этапе основное действие называется HomeActivity, а фрагмент (я его покажу) - HomePacksFragment.Приложение о животных, и фрагмент показывает пакеты их, поэтому он называется так.

1) У меня есть два модуля: PresentersModule, предоставить докладчиков для HomeActivity и HomePacksFragment:

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

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

и 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) Тогда у меня есть компонент AppComponent, который знает все мои модули и может внедрять зависимости в конкретном представлении:

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

    DAO animalDao();
    AnimalDatabase animalDatabase();
}

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

Идея этого класса заключалась в том, чтобы предоставить единственные приложения AppComponent.Технически это работает, но что если у меня 10 или 20 просмотров?Класс расширенный Application является базовым классом, он не будет содержать только AppComponent логики создания, и многое другое будет здесь.Я правильно пишу?

4) Это конец.Я создаю 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);
    }
}

Я делаю правильные вещи или я должен что-то изменить, пока не стало слишком поздно?

UPD:

Хорошо, я заглянул в простой пример 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;
    }

Это выглядит лучше и чище, чем мой, но у меня есть вопрос.В этом примере мы всегда возвращаем basicComponent, так что это означает, что он должен включать все модули?Это нормальная практика, чтобы создать "бог" компонент?=)

Если у меня есть 3 модуля, мне нужно написать (для моего примера):

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

1 Ответ

0 голосов
/ 02 марта 2019

в соответствии с моей идеей и ссылкой, как вы сказали, что вы неправильно используете AnimalsLibraryApp в классе приложения, вам просто нужно объявить один компонент кинжала, тогда в каждом представлении вы будете вставлять модуль с этим компонентом в представление, если вы Googleобразец dagger2 и проверьте класс, который расширил приложение, которое вы поймете

...