草庐IT

php - ServiceLocator,让我们在 ZF2 上下文中考虑一下

coder 2024-04-06 原文

根据 Marco 的 Pivetta 想法 this , 这个old question 以及我对 an other question 的回答

我在自问在 Zend Framework 2 应用程序中使用我们的服务的更好方法。

实际上我们可以结合使用ServiceLocatorAwareInterfaceServiceLocatorAwareTrait。 有了事实In ZF3 service locator will be removed in controller有可能他们也会删除这个接口(interface),或者建议人们不要使用它,这是有道理的。

我了解我们的服务如何构建的唯一方法是:

Don't use ServiceLocator in your Services, use DependancyInjection.

问题是:

有些项目太大了,你有:

  • 一个工作流有 15 个服务类。
  • 具有 15 个依赖项的服务类。
  • 选择你的噩梦......

您在服务中可能需要的一些示例:

  • 取回formManager(不能在controller中调用)
  • 在通过 AJAX 和 JSON 响应将 HTML 字符串返回到 View 之前,您可能需要让 ViewRenderer 呈现模板;
  • 您可能需要取回翻译器或您想要的 ZF2 提供的每项服务
  • 获取您的实体管理器,如果您有多个数据库,请在此处添加计数
  • 获取其他服务,如 MailService、ExportService、ImportService 等...
  • 如果您必须加载特定服务取决于客户端(BtoB 中的多客户端网站...添加一些服务,因为您无法加载 | 调用 AbstractFactory)

也许对于其中一些点,它们可以通过我不知道的技巧来解决。

My Question is :

Is it a good practise to have 15 or more Dependancies for one service and give up the ServiceLocator, in controllers, but also in services ?

根据评论编辑

为了说明我的观点,我粘贴了我的构造函数之一:

public function __construct(
    ToolboxService $toolboxService,
    EntityService $entityService,
    UserService $userService,
    ItemService $itemService,
    CriteriaService $criteriaService,
    Import $import,
    Export $export,
    PhpRenderer $renderer
) {
    $this->toolboxService = $toolboxService;
    $this->entityService = $entityService;
    $this->userService = $userService;
    $this->emOld = $this->toolboxService->getEmOld();
    $this->emNew = $this->toolboxService->getEmNew();
    $this->serviceLocator = $this->toolboxService->getServiceLocator();
    $this->itemService = $itemService;
    $this->criteriaService = $criteriaService;
    $this->import = $import;
    $this->export = $export;
    $this->renderer = $renderer;
    $this->formManager = $this->toolboxService->getFormManager();
}

如您所见,ToolboxService 是一个本身具有多个依赖项的对象。该服务在我的应用程序文件夹中,几乎无处不在。 我有 2 个实体管理器(连接到 2 个数据库,但也许很快,我将需要第三个......)

您可以看到我通过依赖项使用了 serviceLocator,因此该服务没有实现 ServiceLocatorAwareInterface。如果我不使用它,我的 AbstractFactory 调用简直是一团糟

// Distribute somes orders depends on Clients
$distributionClass = $this->serviceLocator->get(ucfirst($param->type));
            if ($distributionClass instanceof DistributeInterface) {
                $distributionClass->distribute($orders, $key);
            } else {
                throw new \RuntimeException("invalid_type_provided", 1);
            }

最佳答案

假设您要注入(inject) ServiceLocator 实例。无法保证 ServiceLocator 实际上持有您的硬依赖项,从而破坏了 DI 模式。使用构造函数依赖注入(inject)时,您可以确定所需的所有服务都确实可用。否则,服务的构建将完全失败。

当使用 ServiceLocator 时,您将最终进入一个实例化的服务类,其中硬依赖项可能通过 ServiceLocator 可用,也可能不可用。这意味着您必须编写所有类型的附加逻辑(检查依赖项、抛出异常),以防无法在您请求时从 ServiceLocator 实例解析依赖项。编写所有这些代码可能比注入(inject) 15 个依赖项需要更多的工作,而且最重要的是整个服务的逻辑会变得困惑。

此外,您仍然需要添加所有 setter 和 getter 方法,以便能够从 ServiceLocator 获取您的服务并使您的服务可测试。

恕我直言,注入(inject) 15 个依赖项比注入(inject) ServiceLocator 实例代码更少,更易于维护。

关于php - ServiceLocator,让我们在 ZF2 上下文中考虑一下,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33496279/

有关php - ServiceLocator,让我们在 ZF2 上下文中考虑一下的更多相关文章

  1. ruby - 在 Ruby 中,在类方法的上下文中,什么是实例变量和类变量? - 2

    如果我有以下一段Ruby代码:classBlahdefself.bleh@blih="Hello"@@bloh="World"endend@blih和@@bloh到底是什么?@blih是Blah类中的一个实例变量,@@bloh是Blah类中的一个类变量,对吗?这是否意味着@@bloh是Blah的类Class中的一个变量? 最佳答案 人们似乎忽略了该方法是类方法。@blih将是常量Bleh的类Class实例的实例变量。因此:irb(main):001:0>classBlehirb(main):002:1>defself.blehirb

  2. ruby - 在 Ruby 中的另一个上下文中评估潜在的相对 URI - 2

    我在Ruby程序中有两个URI。一个肯定是绝对URI,另一个可能是绝对URI或相对URI。我想在第一个的上下文中将第二个转换为绝对URI,所以如果第一个是http://pupeno.com/blog第二个是/about,结果应该是http://pupeno.com/about.有什么想法吗? 最佳答案 Ruby的内置URI和Addressablegem,做这个简短的工作。我更喜欢Addressable,因为它功能更全面,但URI是内置的。require'uri'URI.join('http://pupeno.com/blog','/

  3. ruby - 有人可以解释一下在 Ruby 中注入(inject)的真实、通俗易懂的用法吗? - 2

    我正在学习Ruby,遇到了inject。我正处于理解它的风口浪尖,但当我是那种需要真实世界的例子来学习一些东西的人时。我遇到的最常见的例子是人们使用inject来添加一个(1..10)范围的总和,我不太关心这个。这是一个任意的例子。在实际程序中我会用它做什么?我正在学习,所以我可以继续使用Rails,但我不必有一个以Web为中心的示例。我只需要一些我可以全神贯注的目标。谢谢大家。 最佳答案 inject有时可以通过它的“其他”名称reduce更好地理解。它是一个对Enumerable进行操作(迭代一次)并返回单个值的函数。它有许多有

  4. Ruby 将上下文分配给 lambda? - 2

    是否可以不为lambda分配上下文?例如:classRuledefget_rulereturnlambda{putsname}endendclassPersonattr_accessor:namedefinit_rule@name="ruby"Rule.new.get_rule.call()#shouldsay"ruby"butsaywhatobjectofclassRull,doesnothavevariablename#orself.instance_eval&Rule.new.get_ruleendend我的目标是->没有上下文的存储过程对象,并在特定位置调用之前分配上下文。可能

  5. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  6. ruby - 从上面的上下文返回 - 2

    这个问题的表述并不复杂,但我会尽力而为。通过我们的代码,我们有一些片段,例如response=do_something()returnresponseunlessresponse.ok?我想写一个包装器方法,这样就不需要这一步了,它看起来像这样defrr(&block)response=yieldunlessresponse.ok?#somehowdoreturnbutincontextabove(magicneededhere)endresponseend之后我就可以将上面的代码最小化为response=rr{do_something()}似乎不可能,但这是Ruby所以也许有办法吗?

  7. ruby - 调用 instance_eval(&lambda) 传递当前上下文时出现错误 'wrong number of arguments' - 2

    要清楚-此代码运行完美-codewithproc但如果我将Proc.new更改为lambda,则会出现错误ArgumentError:wrongnumberofarguments(1for0)这可能是因为instance_eval想要将self作为参数传递,而lambda将其视为一种方法并且不接受未知参数?有两个例子-第一个是工作:classRuledefget_ruleProc.new{putsname}endendclassPersonattr_accessor:namedefinit_rule@name="ruby"instance_eval(&Rule.new.get_rule

  8. ruby-on-rails - Ruby on Rails : Acts as taggable on gem, 在模型中使用上下文 - 2

    我想知道是否有人可以帮助我理解文档中的这一部分:Withthedefinedcontextinmodel,youhavemultiplenewmethodsatdisposaltomanageandviewthetagsinthecontext.Forexample,with:skillcontextthesemethodsareaddedtothemodel:skill_list(andskill_list.add,skill_list.removeskill_list=),skills(plural),skill_counts.我有这个:型号:classProjectControl

  9. Ruby 相当于 "grep -C 5"以获取匹配项周围的行的上下文? - 2

    我搜索了一下,但我一定是使用了错误的术语-ruby​​是否有办法grep查找字符串/正则表达式并返回周围的5行(上方和下方)?我知道我可以调用"grep-C5..."或什至编写我自己的方法,但这似乎是ruby​​应该有的东西,我只是没有使用正确的搜索词。 最佳答案 您可以使用正则表达式来完成。这是我们要搜索的字符串:s=%{ThefirstlineThesecondlineThethirdlineThefourthlineThefifthlineThesixthlineTheseventhlineTheeightlineThenin

  10. ruby-on-rails - 你能解释一下这段 Ruby 代码中发生了什么吗? - 2

    我现在正在努力学习Ruby和RubyonRails。我正在学习LearningRails,第1版,但我很难理解其中的一些代码。我通常使用C、C++或Java工作,因此Ruby对我来说是一个很大的改变。我目前对数据库迁移器的以下代码块感到困惑:defself.upcreate_table:entriesdo|t|t.string:namet.timestampsendendt变量来自哪里?它实际上代表什么?它有点像for(i=0;i另外,:entries是在什么地方定义的?(entries是我的Controller的名称,但是这个函数怎么知道的?) 最佳答案

随机推荐