Dagger 2:在不同库模块上的多个具有相同Scope的Component之间提供相同的实例 [英] Dagger 2: Provide same instance between multiple Component with same Scope on different library modules

查看:126
本文介绍了Dagger 2:在不同库模块上的多个具有相同Scope的Component之间提供相同的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Core Android库,我使用@Singleton范围定义CoreComponent广告,以注入CoreModule提供的类实例。

I have a Core Android Library where I'm defining a CoreComponent ad using the @Singleton scope to inject instances of classes provided by a CoreModule.

@Singleton
@Component(modules = {CoreModule.class})
public interface CoreComponent {
    void inject(SomeClass target);
}

@Module
public class CodeModule {
    @Singleton
    @Provides
    CoreRepository provideCoreRepository() {
        return new CoreRepositoryImpl();
    }
}

我想访问相同的@Singleton实例另一个Android库依赖于核心库并使用另一个组件。

I would like to access the same @Singleton instances from another Android Library that is depending on the Core Library and is using another component.

@Singleton
@FooScope
@Component(modules = {CoreModule.class, FooModule.class})
public interface FooComponent {
    void inject(SomeActivity target);
}

public class FooActivity extends AppCompatActivity {
    @Inject
    public CoreRepository repo;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        injectDependencies();
        super.onCreate(savedInstanceState);
    }
    [...]
}

代码上面的版本,但@Singleton范围是组件的本地。换句话说,有两个单例实例,一个用于CoreComponent,另一个用于FooComponent。

The code above builds but the @Singleton scope is "local" to the Component. In other words there are two singleton instances, one for the for the CoreComponent and one for the FooComponent.

Android Application
├── Foo Library
|   └── Core Library
├── Bar Library
|   └── Core Library
·
·
·
└── Core Library

我认为最好的解决方案应该是使用子组件,但遗憾的是,似乎不可能,因为核心库没有其他库的可见性。

I think that the best solution should be using a Subcomponent but, unfortunately, doesn't seem possible because the Core Library has no visibility of the other libraries.

如果使用相同的Scope注释类,是否有另一种方法可以与Dagger共享组件中一个类的相同实例?

Is there another way to share with Dagger the same instance of one class between components if the class is annotated with the same Scope?

推荐答案

CoreComponent 中删除​​注入站点 - 它现在唯一的功能是公开 CoreRepository的绑定到其依赖组件:

Remove the injection sites from your CoreComponent - it now has the sole function of exposing the binding for CoreRepository to its dependent components:

@Singleton
@Component(modules = {CoreModule.class})
public interface CoreComponent {
    CoreRepository coreRepository();
}

在应用程序中创建对此单例范围组件的引用:

Create a reference to this singleton-scoped component inside your application:

public class MyApplication extends Application {
    private final CoreComponent coreComponent;

    @Override
    public void onCreate() {
        super.onCreate();
        coreComponent = DaggerCoreComponent
                            .coreModule(new CoreModule())
                            .build();
    }

    public static CoreComponent getCoreComponent(Context context) {
        return ((MyApplication) context.getApplicationContext()).coreComponent;
    }
}

创建一个新的更窄的范围:

Create a new narrower scope:

@Scope
@Retention(RetentionPolicy.RUNTIME) public @interface PerActivity {}

使用您想要的注射网站创建一个跟踪此范围的新组件:

Create a new component that tracks this scope complete with the injection sites you want:

@PerActivity
@Component(dependencies = {CoreComponent.class})
public interface ActivityComponent {
    void inject(FooActivity activity);

    void inject(BarActivity activity);
}

当您在注入网站中访问此活动范围的组件时,您将需要向构建器提供 CoreComponent 的实例。现在你可以注入你的活动

When you access this activity-scoped component in the injection site, you will need to provide the instance of CoreComponent to the builder. Now you can inject into your Activity

public class FooActivity extends AppCompatActivity {
        @Inject
        public CoreRepository repo;

        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            CoreComponent coreComponent = MyApplication.getCoreComponent(this);
            DaggerActivityComponent.builder()
                .coreComponent(coreComponent)
                .build()
                .inject(this);
        }
    }
}

这篇关于Dagger 2:在不同库模块上的多个具有相同Scope的Component之间提供相同的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆