【问题标题】:[Dagger 1.x]: Specifying the ObjectGraph itself as a dependency for a class?[Dagger 1.x]:将 ObjectGraph 本身指定为类的依赖项?
【发布时间】:2015-03-31 06:59:55
【问题描述】:

TL;DR;

类依赖于 ObjectGraph 本身是否可以接受?


我需要这个,因为我需要在运行时加载的一些对象上注入依赖项——此时与初始化 ObjectGraph 的点断开连接。这是一个示例,说明我如何使用ServiceLoader 框架在运行时加载服务的具体实现类,然后将依赖项注入到加载的实现类中。

interface Plugin {
    void doSomething();
}

class AwesomePlugin implements plugin {
    @Inject DependencyOne dependencyOne; 
    @Inject DependencyTwo dependencyTwo;
    void doSomething(){
        // ...some implementation...
    }
}

class PluginEngine{
    public void start(){
        ServiceLoader<Plugin> pluginLoader = ServiceLoader.load(Plugin.class);
        for(Plugin plugin: pluginLoader){
            //TODO: Inject plugin dependencies here
        }
    }
}

这样做需要PluginEngine 类可以访问ObjectGraph 实例:

class PluginEngine{
    private final ObjectGraph objectGraph;
    
    public PluginEngine(ObjectGraph graph){
        this.objectGraph = graph;
    }
    
    public void start(){
        ServiceLoader<Plugin> pluginLoader = ServiceLoader.load(Plugin.class);
        for(Plugin plugin: pluginLoader){
            objectGraph.inject(plugin);
        }
    }
}

这是代码异味吗?这是否指向我的代码中其他地方的一些问题,或者我的依赖项的设置方式?

在撰写此问题时,我开始将 Dagger 的作用视为将任意依赖项替换为对 ObjectGraph 本身的依赖项的一种方式。在 Android 上,您使用对自定义 Application 子类的引用并使用它来执行注入 - 这基本上只是访问 ObjectGraph 本身的一种手段。这个推理有问题吗?

【问题讨论】:

  • @EpicPandaForce 这是针对 Dagger 1.x 的。编辑标题以澄清这一点。 IIRC,Dagger2 根本没有 ObjectGraph。
  • 啊,好吧。我很好奇,因为我没有使用过 Dagger2(只有 Dagger1),但从未遇到过ServiceLoader&lt;T&gt;。那是你自己的代码吗?我认为你不能在没有...的情况下获得@Inject Objectgraph objectGraph 依赖项,用objectGraph.inject(this) 注入它,你需要objectGraph,你不能单独注入它,因此我认为这不会工作,除非这里有我看不到的东西。
  • @EpicPandaForce ServiceLoader 是一个通用的 Java 工具,用于在运行时加载具体的实现类。这是 Android 文档的链接 - 但它也可用于其他 Java 实现 - developer.android.com/reference/java/util/ServiceLoader.html。您无法注入 ObjectGraph 本身是对的。我可能应该把它移到构造函数参数中。
  • 啊。然后我将阅读有关 ServiceLoaders 的信息。我个人使用下面的设置,从Android Bootstrap生成的代码中抢了结构:stackoverflow.com/a/27036934/2413303

标签: android dagger


【解决方案1】:

回答我自己的问题,看起来这是可以接受的。 u2020 sample app 做了类似的事情。事实上,它非常巧妙地使用了getSystemService() 来实现这一点,但这是特定于Android 的。特别是查看Injector.java 以及如何在自定义视图中使用它,例如TrendingView

因此,从概念上讲,可以做这样的事情 - 它基本上抽象了 Injector 接口后面的具体 ObjectGraph 依赖项。

class PluginEngine{
    private final Injector injector;

    public PluginEngine(Injector injector){
        this.injector = injector;
    }

    public void start(){
        ServiceLoader<Plugin> pluginLoader = ServiceLoader.load(Plugin.class);
        for(Plugin plugin: pluginLoader){
            injector.inject(plugin);
        }
    }
}

这可以通过各种方式进行细化/调整,以便通过构造函数提供注入器依赖项或以其他方式获得。

【讨论】:

    猜你喜欢
    • 2011-11-03
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    • 2018-03-09
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多