Как ввести мой класс приложения для комнаты - PullRequest
0 голосов
/ 27 октября 2019

Меня очень смущает вопрос о кинжале 2. Существует множество способов, которыми люди предлагают решение. Как я могу ввести свое приложение для предоставления своей базы данных?

У меня уже есть модуль базы данных, модуль приложения, обеспечивающий мое приложение. Мой компонент приложения с компоновщиком внутри (понятия не имею, что он делает). С этим компоновщиком невозможно построить его внутри моего класса приложения!?

Класс приложения:

public class OnSiteApplication extends Application implements HasActivityInjector {
    @Inject
    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public AndroidInjector<Activity> activityInjector() {
        return dispatchingAndroidInjector;
    }
}

AppComponent:

@Singleton
@Component(modules = {ApplicationModule.class, AndroidInjectionModule.class})
public interface AppComponent extends AndroidInjector<OnSiteApplication> {

    @Component.Builder
     interface Builder {
        @BindsInstance
        Builder application(Application application);

        AppComponent build();
    }

    void inject(OnSiteApplication onSiteApplication);
}

Модуль приложения:

@Module(includes = DatabaseModule.class)
public class ApplicationModule {
    private static final String SHARED_PREFERENCE_NAME = "OnSitePreferences";

    private final OnSiteApplication application;

    public ApplicationModule(OnSiteApplication appContext) {
        this.application = appContext;
    }

    @Provides
    public OnSiteApplication provideOnSiteApplication() {
        return application;
    }
}

Модуль базы данных:

@Module
public class DatabaseModule {
    @Provides
    public static OnSiteDatabase provideDatabase(Application appContext) {
        return Room.databaseBuilder(appContext,
                OnSiteDatabase.class, OnSiteDatabase.DATABASE_NAME)
                .fallbackToDestructiveMigration()
                .build();
    }

    @Provides
    public static ProjectDao provideProjectAccess(OnSiteDatabase onSiteDatabase) {
        return onSiteDatabase.projectDao();
    }

}

Большинство решений - один год или старше. Каков самый современный способ внедрения классов на основе ОС, таких как Application?

1 Ответ

1 голос
/ 27 октября 2019

В вашей реализации есть несколько проблем:

Проблема - 1: Вы указываете DatabaseModule как зависимость от ApplicationModule, что неверно, поскольку DatabaseModule никогда не использовался внутри ApplicationModule. Скорее вы можете передать ApplicationModule в DatabaseModule, так как контекст приложения используется для создания базы данных. [ Но это не обязательно, проверьте ниже ]

Проблема - 2: Здесь ApplicationModule бесполезен, так как Application уже предоставлен через @BindsInstance. Таким образом, вы можете удалить ApplicationModule отсюда.

Таким образом, окончательная реализация выглядит так:

@Singleton
@Component(modules = {DatabaseModule.class, AndroidInjectionModule.class})
public interface AppComponent extends AndroidInjector<OnSiteApplication> {

    @Component.Builder
     interface Builder {
        @BindsInstance
        Builder application(Application application);

        AppComponent build();
    }

    void inject(OnSiteApplication onSiteApplication);
}

И OnSiteApplication, создайте AppComponent, как показано ниже:

public class OnSiteApplication extends Application implements HasActivityInjector {
    @Inject
    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;

    AppComponent appComponent;

    @Override
    public void onCreate() {
        super.onCreate();
        appComponent = DaggerAppComponent.builder().application(this).build();
    }

    public AppComponent getAppComponent() {
        return appComponent;
    }

    @Override
    public AndroidInjector<Activity> activityInjector() {
        return dispatchingAndroidInjector;
    }
}
...