首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Dagger2向组件添加范围标记的目的是什么?

Dagger2向组件添加范围标记的目的是什么?
EN

Stack Overflow用户
提问于 2015-12-21 13:46:35
回答 2查看 313关注 0票数 0

我已经创建了一个组件,它只持续到活动的整个生命周期。我没有使用任何范围注释,只使用了该组件生命周期的快速示例如下所示:

代码语言:javascript
运行
复制
public class MainActivity extends AppCompatActivity {

private final String TAG = getClass().getSimpleName();
@Inject
AlmondButter someAlmondButter;
@Inject
CashewSandwich sandwich;

SandwichComponent sandwichComponent;

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

    /*create thte dependent butter for the sandwich here*/
    ButterComponent butterComponent=DaggerButterComponent.builder().
            butterModule(new ButterModule()).build();
    /*create a scope sandwichcomponent here */

    sandwichComponent=DaggerSandwichComponent.builder().sandwichModule(new SandwichModule()).
            butterComponent(butterComponent)
            .build();
    //finally we have a sandwichComponent, lets inject our dependencies
    sandwichComponent.inject(this);

    Log.v(TAG,sandwich.toString());
    Log.v(TAG,someAlmondButter.toString());
}

@Override
protected void onDestroy() {
    super.onDestroy();
    //not necessary but it clearly shows the scope being tied to lifecycle of activity
    sandwichComponent=null;
}

}

我的组件中没有一个是通过模拟来限定范围的,而且工作正常。所以我搞不懂为什么有人建议创建范围标签,目的是什么?我将向您展示下面的组件,以供参考:

代码语言:javascript
运行
复制
    @Component(dependencies = ButterComponent.class, modules = SandwichModule.class)
public interface SandwichComponent {
    CashewSandwich ProvideCashewSandwitch();
    void inject (MainActivity mainactivity);
}

下一个组成部分是:

代码语言:javascript
运行
复制
    @Component(modules={ButterModule.class})

public interface ButterComponent {
     //these are for our whatever class depends on butter
     AlmondButter ProvideAlmondButter();
     CashewButter ProvideCashewButter();
}

更新:对于任何需要帮助理解这些概念的人,我创建了一个博客这里。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-21 16:30:06

通过在组件上使用作用域和在模块提供程序方法上使用作用域,您可以要求Dagger2为您创建scoped providers

为了在模块的provider方法中获得作用域提供程序,还必须将作用域放在组件上。

您只能在给定组件上指定一个作用域,而在作用域组件中,只能在其提供程序方法上拥有具有该作用域的模块,或者也可以取消提供程序方法的作用域。

非作用域提供者在每次注入调用时都会为您提供一个新实例。作用域提供程序为每个对该特定组件实例的注入调用存储一个实例。

代码语言:javascript
运行
复制
@Component(modules={HelloModule.class})
@Singleton
public interface HelloComponent {
    Hello hello();
    World world();

    void inject(MainActivity mainActivity);
}

@Module
public class HelloModule {
    @Provides
    public Hello hello() { return new Hello(); } //new instance each call to inject

    @Provides
    @Singleton
    public World world() { return new World(); } //one instance per component
}

还值得注意的是,如果您对另一个组件进行子范围以继承其依赖项(使用子组件或组件依赖项),则只能依赖于另一个作用域组件。就像Java中不允许“多重继承”一样,您也不能依赖于多个作用域组件并继承它们的依赖项,只有一个。

通常,您有一个单例作用域,并且根据应用程序中模块的顶层分离对组件进行子范围。

代码语言:javascript
运行
复制
@Component(modules={ApplicationModule.class})
@Singleton
public interface ApplicationComponent {
    Something something();
}

@Component(dependencies={ApplicationComponent.class}, modules={MainActivityModule.class}) 
@ActivityScope 
//this is a subscoped component that inherits from ApplicationComponent
public interface MainActivityComponent extends ApplicationComponent {
    OtherThing otherThing();

    void inject(MainActivity mainActivity);
}

根据Martin,等等,而不是按层(数据、域、表示)。

票数 3
EN

Stack Overflow用户

发布于 2015-12-21 15:37:06

作用域管理同一类型的多个请求之间的实例创建。想象一下如果你有这个:

代码语言:javascript
运行
复制
@Inject
AlmondButter someAlmondButter;
@Inject
AlmondButter otherAlmondButter;

这将创建两个单独的AlmondButter实例。这是一个很小的例子,但希望它说明了一点:每次请求依赖项时,都会创建一个新的依赖项。

想象一下,现在您有两个不同的类,每个类都有一个字段@Inject AlmondButter sharedAlmondButter。如果希望它们具有相同的实例,作用域将为您处理这个问题。

类似地,对于您拥有的任何依赖项,您都可以注入一个Provider<T>,即@Inject Provider<AlmondButter> almondButterProvider。这允许您调用almondButterProvider.get()来检索新实例。如果您希望.get()返回的所有值都是同一个实例,那么作用域将完成相同的任务。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34397211

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档