本文介绍了Symfony2/Doctrine,必须将业务逻辑放在我的控制器中?和复制控制器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序中有一个有点复杂的定价机制 - 以下是我设置阶段的一些业务规则(实体是粗体):

I have a somewhat complex pricing mechanism in my application- Here are some of my business rules to set the stage (Entities are bolded):

  • 对于给定的客户网站客户,产品可能具有独特的价格点.
  • 一个产品有时可以有一个或多个额外的选项,这些选项可能有自己的价格点 价格规则.
  • 一个产品有一个由用户选择的唯一添加,它本质上是一个价格和一个整数.
  • A Product may have unique Price Points for a given Customer, Website, or Customer Group.
  • A Product can sometimes have one or more additional Options that may have their own Price Points or Price Rules.
  • A Product has one Unique Addition selected by the user, which is essentially a price and an integer.

现在,我有一个 价格点 的 EntityRepository 来确定基本产品的正确价格点.Unique AdditionOptions 也是如此.

Right now, I have an EntityRepository for Price Points to essentially determine the correct price point for the base product. The same goes for the Unique Addition and the Options.

public function getThePrice($Product, $qty, $Website, $Customer = null)
{
    //all logic to get product price for this given instance goes here. Good.
}

控制器(简化)

public function indexAction()
{
    $Product = $em->dostuffwithpostdata;
    $qty = POST['qty']; //inb4insecure trolls
    $Website = $em->dostuff();
    $Customer = (if user is logged in, return their object with $em, otherwise null as it is a guest or public person); // No business logic here, just understanding the request.

    $price = $em->getRepository(PricePointRepository)->getThePrice($Product,$qty,Website,$Customer);

    $Options[] = $em->dostuffwithPOSTdata;
    $optionsPrice = 0;
    //Below is some logic directly related to pricing the product.
    foreach($Options as $option) {
        if($option->hasRule()) {
            $optionsPrice += $ruleprice; //after some other stuff of course)
        } else {
            $optionsPrice += $em->getRepository(OptionPricePoints)->getPrice($option->getID(),$qty);
        }
    }

    $uniqueAdditionPrice = $em->stuff;

    $finalprice = $price + $optionsPrice + $uniqueAdditionPrice; //This is logic related to how I price this type of product!
    $unitprice = $finalprice / $qty;

    //twig stuff to render and show $finalprice, $unitprice, $uniqueAdditionPrice
}

这仅适用于产品页面.当这个逻辑需要重用时,当我到达购物车、保存订单等时会发生什么.如您所见,我始终使用 Doctrine 根据存储库类中的业务逻辑提取数据.

That's just for the product page. What happens when I get to the cart, saving the order, etc, when this logic needs to be reused. As you can see, I use Doctrine throughout to pull data based on my business logic in the repository classes.

我很高兴地欢迎 urdoingitwrong 的回答,因为我确实认为这是错误的.我该如何解决这个问题?本质上是这样的服务:

I gladly welcome urdoingitwrong answers, because I really do think this is wrong. How do I go about fixing this? Something beautiful would be a service that essentially goes like this:

$pricer = getPricerService->Pricer($Entities,$postdata,$etc);
$unitPrice = $pricer->getUnitPrice();
$totalPrice = $pricer->getTotalPrice();
$optionsPrice = $pricer->getOptionsPrice();

但我不知道如何在 Symfony/Doctrine 内部执行此操作,尤其是在控制器中访问 Doctrine 和 Repositories 的方式.

But I have no idea how to go about doing that inside of Symfony/Doctrine, especially the way Doctrine and Repositories are accessed in Controllers.

推荐答案

您是正确的,您应该将所有可重用的业务逻辑转移到服务中,以便不同的控制器可以重用代码.

You're correct that you should have all your re-usable business logic farmed off to a service so that different controllers can re-use the code.

>

您是否查看过如何创建服务"文档:

Have you checked out the "how to create a service" documentation:

服务容器文档

不过我会给你减速.

在 config.yml 中你需要定义你的服务:

In config.yml you need to define your service:

services:
    pricing_service:
        class: AcmeProductBundleServicePricingService
        arguments: [@doctrine]

然后你只需要制作一个 bog 标准的 PHP 类来表示你的服务:

Then you just need to make a bog standard PHP class to represent your service:

namespace AcmeProductBundleService;

class PricingService {

    private $doctrine;

    function __construct($doctrine) {
        $this->doctrine = $doctrine; // Note that this was injected using the arguments in the config.yml
    }

    // Now the rest of your functions go here such as "getUnitPrice" etc etc.
}

最后,要从控制器获取服务,您只需要执行以下操作:

Lastly to get your service from a controller you just need to do:

$pricingService = $this->get('pricing_service');

还有其他方法可以模块化服务,例如不将所有服务转储到 config.yml 中,但所有这些都在文档中进行了解释.另请注意,您可以将任何其他服务注入您的服务中,因此如果您需要诸如 arguments: [@doctrine, @security.context, @validator] 之类的内容,您可以执行所有这些操作,甚至:[@my_other_service].

There are other ways you can modularise the service such as not dumping all your services into config.yml but all of that is explained in the documentation. Also note that you can inject any other service you wish into your service so if you need stuff like arguments: [@doctrine, @security.context, @validator] you can do all that stuff or even: [@my_other_service].

我怀疑从您关于注入 EntityManager 的其他问题中,您可能已经意识到这是要走的路!

I suspect from your other question on injecting the EntityManager you may have already gleamed this was the way to go though!

希望这对你仍然有用!

这篇关于Symfony2/Doctrine,必须将业务逻辑放在我的控制器中?和复制控制器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 12:58