我正在使用Symfony2和Doctrine ORM,并希望通过干净的架构实现以下目标:
每次创建新实体时,我都希望保存最终用户选择的"显示名称",然后根据"显示名称"生成"唯一名称"。
如果我的最终用户想要创建 3 个名为"图纸"的项目,
- 第一个将具有display_name="图纸">
- 第二个将有 display_name = "图纸2">
- 第三个将具有display_name = "图纸3">
(或类似的东西,无论模式如何(
基本实体示例:
/**
* Project.
*
* @ORM'Entity
*/
class Project
{
//...
/**
* @ORM'Column(type="string", length=50, nullable=false)
*/
protected $name_display ;
/**
* @ORM'Column(type="string", length=50, nullable=false, unique=true)
*/
protected $name_unique ;
//...
基本使用示例:
$project = new Project();
$project->setDisplayName('Drawings');
//Around here I would like the Unique name to be generated
$this->getDoctrine()->getManager()->persist($project);
我想到了各种解决方案:
- 在控制器中生成名称,但不可重用
- 在存储库中生成唯一名称。但这似乎是一个糟糕的做法(存储库应该是只读的(
- 使用预持久生命周期原则中的回调,但这不是一个好的做法,因为我需要实体管理器来做一个数据库
- 在实体资源库中执行名称生成,注入实体管理器以发出请求并查找可用名称。这看起来很可怕
- 使用服务来持久化实体,如下所述:Doctrine2 存储库是保存实体的好地方吗?(但是如果我想让我所有的实体创建都与这种做法保持一致,这非常复杂,并且涉及我的基础设施的巨大变化(
我会推荐最后一个选项 - 服务。它可能需要在您的项目中进行更改,但我发现这是使用实体管理通常的 crud 操作的最佳方式 - 创建、保存、查找 BySomething ......
- 它非常清晰 - 没有黑魔法。与执行的代码与与实体的操作之间没有明显关系的事件相反(例如通过 new 创建它(。
- 它不依赖于注释,并且易于维护。
- 控制器和其他服务可以通过依赖注入访问此服务,这是满足业务对象(保存业务逻辑的对象(依赖关系的明确方式
- 您的仓库不会变得越来越大
- 您可以使用默认存储库 - 升级 Doctrine 时反向兼容性问题更少
- 它比"二传手解决方案"要好得多,这听起来真的很可怕 - 实体永远不应该那么强大,所以他们会引用服务(尤其是像
EntityManager
这样的服务(