为什么要使用闭包进行赋值,而不是直接为键赋值? [英] Why use a closure for assignment instead of directly assigning a value to a key?

查看:122
本文介绍了为什么要使用闭包进行赋值,而不是直接为键赋值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在观看此视频,并在7:10他添加了一个

I was watching this video and at 7:10 he's adding a db dependency and is using a closure to assign the value.

我的问题是,为什么不只使用直接赋值,我的意思是不这样做:

My question is why not just use direct assignment instead, I mean isn't doing this:

$container['db'] = $capsule;

等效于执行以下操作:

$container['db'] = function ($container) use ($capsule) {
    return $capsule;
}

如果没有,有什么区别,哪种方法更好?

If not, what is the difference and which way is better?

推荐答案

TLDR ,这是因为将依赖项定义为闭包使得依赖项注入容器可以按需构建它们,因此您不必担心它们的定义顺序和手动管理其依赖性。

TLDR it's because defining dependencies as closures makes it possible for dependency injection container to build them on demand, hence you don't need to worry about their order of definition and managing their dependencies manually.

Pimple是 Dependency Injection Container ,它应该

Pimple is Dependency Injection Container, it is supposed to help you set up your objects by managing their dependencies in an easy and convenient way.

如果直接为键分配值,则Pimple会调用该值作为参数,当您需要访问该键时,它只返回该确切值:

If you directly assign a value to a key, Pimple calls that value a parameter, and when you need to access that key, it simply returns that exact value:

$container['sample-param'] = 'foo';
echo $container['sample-param'];
//output: foo

但是重点是,这个 sample-param 不需要任何设置,它只是一个值,我们对此表示满意。但是假设以下服务设置:

But the point is, this sample-param does not require any set up, it is simply a value and we're fine with that. But assume the following service setup:

$container['myService'] = function($c) {
    $service = new \Some\Complicated\Service();
    //this service depends on cache service
    $service->setCache($c['cache']);
    return $service;
}

$container['cache'] = function($c) {
    $cache = new \Cache\Driver();
    //our cache driver needs a db connection
    $cache->setDbConnection($c['db']);
    return $cache;
}

$container['db'] = function($c) {
    //our database connection requires some parameters
    $dbConnection = new \Database\Connection($c['db-config']);
    return $dbConnection;
}

$container['db-config'] = [
    'username' => 'foo',
    'password' => 'bar',
    'host' => 'localhost'
];

//Now we want to user our service:
$container['myService']->doSomething();

请注意我用来定义容器中不同键的顺序。

Please pay attention to order which I used to define different keys in the container.

myService 需要缓存,但缓存定义在myService定义之后。这就是Pimple所提供的帮助,这就是我们将容器传递给每个闭包的原因,因为Pimple将按需构建我们的依赖项。当我们需要访问 myService 时,Pimple会查看其内部数据存储,如果它先前已成功构建并存储了 myService ,它会返回相同的实例,否则它将调用我们的闭包来构建它。当调用我们的闭包时,它将要求Pimple($ c是Pimple容器)为其赋予依赖项(在本例中为缓存服务)。 Pimple在缓存上应用相同的东西,如果尚未构建,它将构建它,依此类推...直到达到需要简单参数的部分,例如 db-config 将立即返回。在这个闭包调用链中,我们的对象及其所有依赖项都已构建。

myService needs cache but cache definition comes after myService definition. And this is where Pimple is helping, and this is why we pass container to every closure, because Pimple is going to build our dependencies on demand. When we need to access myService Pimple looks at its internal data storage, if it has previously built and stored myService successfully, it will return that same instance, else it will call our closure to build it. And when our closure is called, it will ask Pimple ($c is the Pimple container) to give it its dependecies (which in this case is the cache service). Pimple applies the same thing on cache, if it is not built yet, it will build it and so on...till it gets to the part that requires simple params like db-config which will immediately return. And in this chain of closure calls, our object and all its dependencies are built.

现在,想象一下如果使用简单值而不是闭包会发生什么?在那种情况下,当我们要构建 myService 时,我们必须照顾它的依赖性。我们必须确保在之前定义了其依赖项,然后定义服务本身,并且我们必须处理与管理依赖项有关的其他问题。在那种情况下,我们不能仅仅定义我们的 myService 假设就有一个缓存服务可用,这将在以后定义。

Now imagine what would happen if we used simple values instead of closures? In that case, when we want to build myService we have to take care of its dependencies. We have to make sure its dependencies are defined before we define the service itself and we have to deal with other problems related to managing dependencies. In that case we couldn't just define our myService and assume there is a cache service available, which will be defined later.

这篇关于为什么要使用闭包进行赋值,而不是直接为键赋值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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