Dan*_*Dan 17 php dependency-injection
我们正在考虑将依赖注入容器集成到我们的项目中.我看过的每个DIC都使用关联数组和/或魔术方法.例如,这是来自Pimple页面的示例:
$container['session_storage'] = function ($c) {
return new $c['session_storage_class']($c['cookie_name']);
};
$container['session'] = function ($c) {
return new Session($c['session_storage']);
};
Run Code Online (Sandbox Code Playgroud)
是否有一个原因?我讨厌在我的代码中使用字符串,而不是将在某处显示的文字字符串.你失去了IDE的强大功能(这使代码难以维护,这是我们试图避免的事情!).
我的偏好更像是:
class Container {
function getSessionStorage()
{
return new $this->getSessionStorageClass($this->getCookieName);
}
function getSession()
{
return new Session($this->getSessionStorage());
}
}
Run Code Online (Sandbox Code Playgroud)
有没有理由不这样做?如果我们走这条路线,我是否会错过一些不会起作用的疙瘩?
oro*_*kek 10
ArrayAccess
Pimple扩展的"神奇之处" 在于它完全可重用且可互操作.作为DIC的Pimple的一个重要特征是定义的服务可以利用先前定义的服务和/或参数.让我们说(无论出于何种原因)你有一个Session
需要Filter
实例的对象.没有DIC你可以写:
$session = new Session(new Filter);
Run Code Online (Sandbox Code Playgroud)
有疙瘩你可以写:
$pimple['filter'] = function($c) {
return new Filter;
};
$pimple['session'] = function($c) {
return new Session($c['filter']);
}
Run Code Online (Sandbox Code Playgroud)
Pimple在Session对象的实例化中使用先前注册的"Filter"服务.这种好处并不是实现的DIC所特有的ArrayAccess
,但可重用性对于代码重用和共享非常有用.您当然可以为某些服务或所有服务硬编码getter/setter,但可重用性的好处几乎丢失了.
另一种选择是使用魔术方法作为getter/setter.这将使DIC的API更像您在代码中所需的API,甚至可以将它们用作Pimple ArrayAccess
代码的包装器(尽管您可能最好在此时编写专用的DIC).包装Pimple的现有方法可能如下所示:
public function __call($method, $args) {
if("set" === substr($method, 0, 3)) {
return $this[substr($method, 3)];
}
if("get" === substr($method, 0, 3) && isset($args[0])) {
return $this[substr($method, 3)] = $args[0];
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
您还可以使用__set
和__get
提供对DIC中的服务和参数的类似对象的访问,如下所示:(仍然包含在Pimple的ArrayAccess
方法中)
public function __set($key, $value) {
return $this[$key] = $value;
}
public function __get($key) {
return $this[$key];
}
Run Code Online (Sandbox Code Playgroud)
除此之外,您可以完全重写DIC以专门使用魔术方法,并且具有类似对象的API语法而不是实现ArrayAccess
,但这应该很容易理解:]
您关心IDE自动完成,因为您将使用您的容器作为服务定位器,即您将打电话给您的容器.
你不应该理想地这样做.服务定位器模式是一种反模式:您可以从容器中获取它们,而不是注入所需的依赖项(依赖注入).这意味着您的代码已耦合到容器.
疙瘩(以及它的数组访问)并没有真正解决这个问题,所以我不是直接回答你的问题,但我希望它能让它更清晰.
旁注:什么是"理想"的方式?依赖注入.
切勿使用或调用容器,除非在应用程序的根目录下(例如创建控制器).始终注入所需的对象(依赖项),而不是注入整个容器.
归档时间: |
|
查看次数: |
2482 次 |
最近记录: |