2016-04-01 2 views
1

Прежде всего, я новичок, только начинаю изучать кинжал, у меня есть некоторые проблемы с пониманием, поэтому надеюсь, что кто-то может мне помочь.Кинжал 2 Объяснение объяснений

Я много читал о кинжале, но до сих пор не могу понять некоторые детали.

Я создал мой ApplicationComponent, и это выглядит как этот

@Singleton 
@Component(modules = { 
     ApplicationModule.class, 
     ThreadingModule.class, 
     NetworkModule.class, 
     DatabaseModule.class, 
     ServiceModule.class, 
     ParseModule.class, 
     PreferencesSessionModule.class}) 

public interface ApplicationComponent { 
    void inject(BaseActivity baseActivity); 
    void inject(MainAppActivity mainAppActivity); 
    void inject(BaseFragment baseFragment); 
} 

И он прекрасно работает все впрыскивает правильно, но теперь я хочу, чтобы погрузиться глубже в крестик API и использовать Custom Scope

я модуль называется PermissionModule он используется для версий Android M.

@PerActivity 
@Module 
public class PermissionModule { 
    @Provides 
    @PerActivity 
    PermissionController providePermissionController(Activity activity) { 
     return new PermissionManager(activity); 
    } 
} 

И я хочу ему быть введен в моей деятельности и быть в памяти только тогда, когда активность также в памяти (actvity жизненный цикл)

@PerActivity 
@Component(modules = { 
     ActivityModule.class, 
     PermissionModule.class 
}) 
public interface ActivityComponent { 
    Activity activity(); 

    void inject(BaseActivity baseActivity); 

    PermissionModule permissionModule(); 
} 

Мои ActivityComponent

@PerActivity 
@Component(modules = { 
     ActivityModule.class, 
     PermissionModule.class 
}) 
public interface ActivityComponent { 
    Activity activity(); 

    void inject(BaseActivity baseActivity); 

    PermissionModule permissionModule(); 
} 

И мои BaseActivity

public abstract class BaseActivity extends AppCompatActivity implements SpiceManagerProvider, NetworkRequestsExecutor { 
    // Dependencies are injected by ApplicationComponent 
    @Inject 
    protected ApplicationSettingsManager mApplicationSettingsManager; 
    @Inject 
    protected SpiceManager mSpiceManager; 
    @Inject 
    protected ScheduledThreadPoolExecutor mPoolExecutor; 

    !!!!!! 
    Should be injected by activity component 
    @Inject 
    protected PermissionController mPermissionController; 

И в onCreate()

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     // Injecting dependencies 
     MyApplication application = MyApplication.get(this); 
     application.getApplicationComponent().inject(this); 
     DaggerActivityComponent.builder().activityModule(new ActivityModule(this)).build().inject(this); 
     mPermissionController.requestPermission(Manifest.permission.ACCESS_FINE_LOCATION); 
     mPermissionController.requestPermission(Manifest.permission.CAMERA); 
     super.onCreate(savedInstanceState); 
    } 

я получил ошибку

PermissionController не может быть обеспечена без @ Provides- или @ Выдает-аннотированный метод. .ui.activities.base.BaseActivity.mPermissionController

Что плохого в моем коде?

Также не создавать новый вопрос и это связано с этой темой.

Как сделать dagger2 parse Scope аннотация, я не могу понять это. Насколько я понимаю, кинжал распознает только аннотацию Singleton, и все остальные аннотации не влияют на решение кинжала, потому что все остальные аннотации будут иметь сферу деятельности?

ответ

1

поэтому проблема заключается в том, что вы вызываете метод впрыскивать ApplicationComponent первый в

application.getApplicationComponent().inject(this); 

, которая пытается внедрить все элементы, в том числе PermissionController. Но ApplicationComponent не может этого обеспечить, и это то, о чем жалуется Dagger.

Решение должно вызывать только метод inject() метода ActivityComponent.

Скорее всего, в какой-то момент вам понадобятся зависимости, предоставляемые ApplicationComponent. Чтобы архивировать это, вам необходимо объединить два компонента.Dagger предусматривает два способа для этого, subcomponents и component dependencies

При использовании зависимостей компонентов, ем бы в конечном итоге с чем-то вроде этого в вашем методе Activity в OnCreate():

DaggerActivityComponent 
      .builder() 
      .applicationComponent(application.getApplicationComponent()) 
      .activityModule(new ActivityModule(this)) 
      .build().inject(this); 

, когда вы измените компоненты, чтобы посмотреть что-то похожий на это:

@PerActivity 
@Component(
    dependencies = ApplicationComponent.class, 
    modules = { 
     ActivityModule.class, 
     PermissionModule.class 
    } 
) 
public interface ActivityComponent { 
    ... 
} 

обратите внимание, что вам необходимо предоставить зависимости явно в ApplicationComponent, когда вам это нужно в ActivityComponent (или любых форсунках)

+0

Спасибо за ответ, только я удивляюсь, это чистый способ сделать это? Или, может быть, есть еще один вариант? – dugdthndwytn

+0

, как я уже говорил, вы можете сделать это и с субкомпонентами. но, кроме объединения графика зависимости и использования результата для решения зависимостей, я не думаю, что есть более чистое решение. определение области видимости также имеет смысл только в том случае, если у вас есть только один граф объектов. иначе вы можете получить несколько экземпляров для области. – nosyjoe

0

Если какая-либо зависимость от родительского компонента (например, @Componenet (model = AppModel.class) общедоступный интерфейс appComponent ...), который вы хотите использовать в дочернем компоненте (@ActivityScope @Component (DEPENDENCY = APPCOMPONENT.class , model = ActivityModel.class) public interface activityComponenet ...), вам нужно разоблачить его в родительском компоненте. Доступны только открытые зависимости ниже по течению (в дочерних компонентах). Вы делаете это, записывая метод из appModel, который должен обеспечивать зависимость ниже по течению в интерфейсе appComponenet. Имя метода не обязательно должно совпадать с именем метода в appModel, а только с типом возвращаемого типа.