依赖注入和未使用的依赖项

3
首先,抱歉我的英语不好,我希望您明白我的意思。
这是我的问题:
假设我有一个MVC应用程序,包括标准的路由器、控制器、模型(service)层和某种类型的数据库连接器。 模型层依赖于数据库连接器,控制器依赖于模型/服务,而顶级的“应用程序”类则依赖于路由器和控制器。 我的对象层次结构如下所示:
App-> ControllerFactory-> ServiceFactory-> DAO-> DbConnection
也许,上述写法看起来不像是最佳的应用架构,但我想集中在另一件事情上: 当我尝试实例化一个App类时,我应该将所有依赖项传递给实例化的类;类依赖关系反过来也有它们自己的依赖关系等等。 结果是,我一次性得到了整个层次堆栈。但如果在某些情况下我不需要访问数据库呢?如果一些控制器用于呈现静态模板而不涉及模型交互呢? 我的意思是,如果在某些特殊情况下,类不需要自己的依赖项(在某些情况下需要),我应该有条件地注入依赖项或其他什么吗? 我真的卡在这一点上,不知道该怎么办。
2个回答

3
更新:在仔细阅读你的问题后,我有另一个建议:是的,每个类都有不同的依赖关系。
不要将每个对象注入到每个其他对象中。例如,一些服务可能需要DAO,因此请注入它们。但是,如果某个服务不需要DAO,请不要注入任何DAO。
如果您有(例如)需要DAO的服务(因此需要DB连接),但不是每种方法都需要的情况下,则我的其余答案是有效的。
你可能正在寻找的是“懒加载”。
这是注入“尚未加载”的依赖项的行为,因此只有在使用时才会加载该对象。
具体来说,这意味着注入代理对象,该对象看起来和行为完全像原始对象(例如,db连接)。
几个DI容器(框架)支持此功能,因此您无需自己创建代理。我以PHP-DI为例(FYI,我在那个项目上工作)。
以下是使用注释的示例:
use DI\Annotation\Inject;

class Example {
    /**
     * @Inject(lazy=true)
     * @var My\Class
     */
    protected $property;

    /**
     * @Inject({ "param1" = {"lazy"=true} })
     */
    public function method(My\Class $param1) {
    }
}

当然,如果您不想使用注释,可以使用任何其他配置(PHP、YAML等)。以下是通过纯 PHP 配置容器的相同示例:

$container->set('Example')
    ->withProperty('property', 'My\Class', true)
    ->withMethod('method', array('param1' => array(
            'name' => 'My\Class',
            'lazy' => true,
        )));

关于延迟注入的文档中可以了解更多内容。


注意:目前您可能没有使用容器(这不是问题),但要处理延迟注入,这需要一定的工作量,您可能需要开始考虑使用一个。


0
如果你的依赖关系构建比较复杂,可以添加一个新的工厂类,该类应包含创建正确对象的所有逻辑。
class AppFactory(){

    __construct(all params){

    }
    build(useDB=true){
        // logic to build
        if(useDB){
            App = new App(new ControllerFactory(new ServiceFactory(new DAO(new DbConnection(params)))))
        } else {
            App = new App(new ControllerFactory(new ServiceFactory(null))))
        }

        return App;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接