php – 为什么在Zend Framework 2中使用Service Manager?
让我说我有一个服务:
namespace HelloworldService; class GreetingService { public function getGreeting() { if(date("H") <= 11) return "Good morning,world!"; else if (date("H") > 11 && date("H") < 17) return "Hello,world!"; else return "Good evening,world!"; } } 我创建一个可调用的 public function getServiceConfig() { return array( 'invokables' => array( 'greetingService' => 'HelloworldServiceGreetingService' ) ); } 那么在我的控制器我可以做: public function indexAction() { $greetingSrv = $this->getServiceLocator() ->get('greetingService'); return new ViewModel( array('greeting' => $greetingSrv->getGreeting()) ); } 据说这使得控制器依赖于服务(和ServiceManager) 更好的解决方案是为该服务创建工厂或在ServiceManager中返回一个关闭,并在控制器中创建一个setter: class IndexController extends AbstractActionController { private $greetingService; public function indexAction() { return new ViewModel( array( 'greeting' => $this->greetingService->getGreeting() ) ); } public function setGreetingService($service) { $this->greetingService = $service; } } 和 'controllers' => array( 'factories' => array( 'HelloworldControllerIndex' => function($serviceLocator) { $ctr = new HelloworldControllerIndexController(); $ctr->setGreetingService( $serviceLocator->getServiceLocator() ->get('greetingService') ); return $ctr; } ) ) 我的问题是为什么?为什么第二种方法比第一种方法好?这是什么意思,控制器是否依赖于服务? 谢谢
默认情况下,ServiceManager注入任何ZF2控制器,因为它扩展了实现ServiceLocatorAwareInterface接口的AbstractController.
第二种方法的形式为“redundancy”,因为除了已经访问ServiceManager实例之外,只要您需要在控制器之间共享服务,就需要为其中的每一个配置注入机制.由于您的控制器已经具有与ServiceManager相关的依赖性,因此使用第一种方法并将您的域相关服务注册到ServiceManager将变得更有意义,从而将访问集中到服务层.
我们假设我们正在建立一个复杂的系统,其中低耦合,可重用性和可重用性提升测试能力.我们的系统是多层次的,我们构建了一切,直到服务层.请注意,到目前为止,我们还没有考虑“MVC”Web层,甚至选择给定的框架. 在我们的服务层(我将考虑这一层,就像这个问题所提到的那样),我们假设我们采用了业务逻辑与对象图构造(或依赖关系解析)之间的分离的principle.所以我们可能有一些复杂的服务是通过工厂建造的. 现在我们的服务层已经建成,我们决定在ZF2上“插上”.当然,我们的服务应该可以从控制器访问,就像你的问题所说明的那样,我们不仅仅是这样做.但是,我们希望避免冗余并利用我们已经构建的功能.我们假设以下工厂: //The following class is a part of our Service layer public class ComplexServiceFactory{ private dependencyA; private dependencyB; public function buildComplexService() { $service = new ComplexService(); $service->setDependencyA($this->dependecyA); $service->setDependencyB($this->dependecyB); return $service; } } 我们现在要做的只是调整(实际扩展)我们的工厂,使其可以被ServiceManager逻辑使用.这个类可以被认为是将系统“插入”ZF2的机制的一部分(实际上是Adapter) public class SMComplexServiceFactory extends ComplexServiceFactory implements ZendServiceManagerFactoryInterface { public function createService(ServiceLocatorInterface $sm) { $this->setDependencyA($sm->get('dependecyA')); $this->setDependencyB($sm->get('dependecyB')); return parent::buildComplexService; } } 通过这样做,我们不会将对象图构造提升到MVC层(否则将是Separation of Concerns违规和不必要的跨层耦合).服务经理我们的“适应”工厂类在某种意义上是我们的依赖解决机制.事实上,我们的系统仍然是可移植的,我们可以选择另一个系统(另一个框架),并且相对于MVC平台的依赖性较低. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |