【问题标题】:Dagger 2 Scopes explanationDagger 2 Scopes 解释
【发布时间】:2016-04-01 07:16:05
【问题描述】:

首先,我是新手,刚开始探索匕首,理解上有些问题,希望有人能帮帮我。

我已经阅读了很多关于匕首的内容,但仍然无法弄清楚某些部分。

我创建了我的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);
}

而且一切都可以正确注入,但现在我想更深入地研究 dagger API 并使用 Custom Scope

我有一个名为 PermissionModule 的模块,它用于 Android M 版本。

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

我希望它被注入到我的活动中,并且只有当活动也在内存中时才在内存中(活动生命周期)

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

我收到了错误

没有@Provides- 或不能提供PermissionController @Produces-注解的方法。 .ui.activities.base.BaseActivity.mPermissionController

我的代码有什么问题?

也不要创建新问题,它与这个主题有关。

dagger2如何解析Scope注解,我想不通。据我了解,匕首只识别Singleton 注释,所有其他注释不会影响匕首决定,因为所有其他注释都将具有活动范围?

【问题讨论】:

    标签: android dependency-injection scope dagger dagger-2


    【解决方案1】:

    所以问题是你先调用ApplicationComponent的注入方法

    application.getApplicationComponent().inject(this);
    

    尝试注入所有成员,包括 PermissionController。但是 ApplicationComponent 不能提供这个,这就是 Dagger 所抱怨的。

    解决办法是只调用ActivityComponent的inject()方法。

    您很可能在某些时候确实需要 ApplicationComponent 提供的依赖项。要归档它,您需要组合这两个组件。 Dagger为此提供了两种方式,subcomponentscomponent dependencies

    当使用组件依赖时,rou 会在你的 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 {
        ...
    }
    

    请注意,当您在 ActivityComponent(或任何注入器)中需要时,需要在 ApplicationComponent 中显式提供依赖项

    【讨论】:

    • 感谢您的回答,我唯一想知道的是这样做是否干净?或者也许还有其他选择?
    • 正如我所提到的,您也可以使用子组件来执行此操作。但除了结合依赖图并使用结果来解决依赖关系之外,我认为没有更清洁的解决方案。只有当您只有一个对象图时,范围界定才有意义。否则你可能最终会得到一个范围的多个实例。
    【解决方案2】:

    如果您想在子组件(@ActivityScope @Component (DEPENDENCY=APPCOMPONENT.class, model= ActivityModel.class) public interface activityComponenet...) 你需要在父组件中公开它。下游(在子组件中)只能访问公开的依赖项。您可以通过从 appModel 编写需要在 appComponenet 接口下游提供依赖的方法来实现。方法名不需要和appModel中的方法名匹配,只需要返回类型计数即可。

    【讨论】:

      【解决方案3】:

      关于你对 Dagger 作用域的困惑,我在此具体说明一些关于作用域的结论

      • 只要同一组件注入无范围的服务,就会创建一个新的服务实例。
      • 第一次注入 @Singleton 范围服务时,它会在注入组件中被实例化并缓存,然后在同一组件注入到相同类型的其他字段时,将使用相同的实例。
      • 自定义用户定义范围在功能上等同于预定义的@Singleton 范围
      • 作用域服务的注入是线程安全的。

      如果你真的想清楚地了解 Dagger 内部如何使用单例和自定义作用域,请关注这篇文章Dagger 2 Scopes : How It Works Internally

      【讨论】:

      • 非常好的答案,唯一的问题是这是一个粗鲁的抄袭!!!伙计 - 复制粘贴其他人的工作,并在 Medium 上作为自己的重新发布......这太低了。这是来源,比你早 2 年:techyourchance.com/dagger-2-scopes-demystified 自己判断。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-07
      相关资源
      最近更新 更多