域服务实现应位于DDD项目结构中的什么位置?如果我们有IDomainInterface和DomainInterface实施,应DomainInterface执行驻留在解决方案/项目的基础设施或核心/域的一部分?
我有一个电子邮件草稿与以下命令的聚合根:addToRecipient,addCcRecipient,addBccRecipient,updateBodyText,uploadAttachment,removeAttachment并在UI我想禁用SEND按钮,如果还没有准备好要发送的草案(即至少有上收件人和正文中有文字)。我知道我不允许查询聚合,但这是唯一可以告诉我可以发送或不能发送电子邮件的消息。
如果我要应用我对事件源和CQRS的了解,则聚合将发出一个EmailIsReadyToBeSent事件,而我的UserEmailDrafts读取模型将选择该事件并以某种方式更新UI,但是,我将必须在每个命令之后检查并发送取消事件,即EmailIsNotReadyToBeSent。
这感觉很复杂,您怎么看?
events domain-driven-design aggregateroot cqrs event-sourcing
我正在一个基于PHP / JS的项目中,在这里我想在后端介绍域驱动设计。我发现命令和查询比CRUD是表达我的公共领域的更好方法,因此我喜欢遵循CQS原则构建基于HTTP的API。这不是安静的CQRS,因为我想在命令和查询端使用相同的模型,但是许多原理是相同的。对于API文档,我使用Swagger。
我找到了一篇文章,该文章通过REST资源(https://www.infoq.com/articles/rest-api-on-cqrs)公开了CQRS 。他们使用5LMT来区分不同的命令,而Swagger不支持。此外,通过将CQS放到面向资源的REST API中,我是否不会失去意图显示接口的好处?我没有找到任何文章或产品直接通过基于HTTP的后端公开命令和查询。
所以我的问题是:直接通过API公开命令和查询是否是一个好主意。它看起来像这样:
POST /api/module1/command1
GET /api/module1/query1
...
Run Code Online (Sandbox Code Playgroud)
它不是REST,但我看不到REST如何为表带来任何好处。维护REST资源将引入另一个模型。而且,在URL中具有命令和查询将允许使用诸如路由框架和访问日志之类的功能。
我正在开发一个应用DDD原则的项目,我创建了一个类聚合(Account),它将包含类(代理)和(代理),其中(Account)在数据库中有表.我的问题是:
我需要为我的每个实体(帐户,代理和代理)创建一个Repository类和一个Service类,或者我应该创建AccountRepository并在其中执行3个类的插入和搜索?
鉴于子集合不能超过x个项目的不变量,域名如何保证在并发/ Web环境中强制实施这种不变量?让我们看一个(经典)示例:
我们有一个Manager与Employees.(假设的)不变量表明经理不能有超过七个直接报告Employee.我们可以这样(天真地)实现这样:
public class Manager {
// Let us assume that the employee list is mapped (somehow) from a persistence layer
public IList<Employee> employees { get; private set; }
public Manager(...) {
...
}
public void AddEmployee(Employee employee) {
if (employees.Count() < 7) {
employees.Add(employee);
} else {
throw new OverworkedManagerException();
}
}
}
Run Code Online (Sandbox Code Playgroud)
直到最近,我才认为这种方法足够好.然而,似乎还有就是它使数据库来存储边缘的情况下更超过七名员工,从而打破不变.考虑这一系列事件:
当再次从数据库中提取域对象时,Manager …
基本上,我的应用程序将像stackoverflow一样工作,你登录和发布的东西,其他人来和互动.
考虑DDD术语,并试图避免贫血模型,我现在面临这样的决定:我的User实体是否应该掌握创建任何更新+删除+检索他的帖子所需的知识,或者我应该回到旧模式我有一个"发布业务服务",将获得UserDTO参考,PostDTO并做一切?
详细信息:
- 我相信我需要某种帖子服务,因为主页面需要列出所有帖子,管理员用户将能够删除任何帖子... -
理想情况下,只有User实体(和其他人继承)从它)应该能够创建帖子
- 我不知道我将如何处理授权(想想阻止垃圾邮件发送者和其他人) -
也许这应该是由User.CreatePost(postDTO)?触发的域名服务?
我正在使用CQRS和Event-Sourcing实施微服务.我已经看到了CQRS的不同实现,这些实现非常复杂.
我已经理解和实现的是我已经为Read(Query)和Write(Command)创建了两个模型,read模型有一个物化视图,而write模型使用了Database,现在每当发生更新时,write模型都会更新数据库并生成一个事件,并将详细信息记录到读取模型已订阅的事件存储中,并且读取模型通过读取事件来更新其物化视图.
我的问题是这种模式是否依赖于CQRS和事件采购的基础?
我正在尝试使用ValueObject学习编码.我有关于VO的抽象实现的问题,而子类扩展了它.孩子们只会实现给定值的验证方法(电子邮件,用户名等).我的第一个VO看起来在下面是业务规则,这些规则在构造函数中进行验证.
final class Email {
private $email;
public function __construct(string $email)
{
$this->validateEmail($email);
$this->email = $email;
}
public function value() : string
{
return $this->email;
}
private function validateEmail(string $email) : void
{
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new IncorrectEmailException();
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我写第二个VO时,我发现了一些不同的模式,只有验证规则(方法validate).所以我想到了一些抽象类实现模式,让child改进验证规则.
abstract class ValueObject {
protected $value;
public function __construct($value)
{
$this->validate($value);
$this->value = $value;
}
public function value()
{
return $value;
}
abstract protected function validate($value) : void;
}
final class Email extends ValueObject …Run Code Online (Sandbox Code Playgroud) 我正在尝试在非基于Web的项目中学习和实现域驱动设计.我有一个主循环,它将在单个工作单元中对很多实体执行多个过程.除非整个循环的工作成功,否则我不希望任何更改被持久化.我正在使用AutoMapper将持久性模型转换为存储库中的域模型,我的服务正在使用存储库在工作之前检索数据.
有一些DDD元素与我的项目不能很好地工作,我希望有人可以告诉我整个过程有什么问题.
以下是我正在努力解决的DDD想法:
这是我正在尝试做的一个例子.
using (var scope = serviceProvider.CreateScope())
{
var unitOfWork = scope.ServiceProvider.GetService<IUnitOfWork>();
var aggregate1Repo = scope.ServiceProvider.GetService<IAggregate1Repository>();
var aggregate2Repo = scope.ServiceProvider.GetService<IAggregate2Repository>();
var aggregate3Repo = scope.ServiceProvider.GetService<IAggregate3Repository>();
var firstService = scope.ServiceProvider.GetService<IFirstService>();
var secondService = scope.ServiceProvider.GetService<ISecondService>();
var aggregate1 = aggregate1Repo.Find(1); //First copy of aggregate1
var aggregate2 = aggregate2Repo.Find(1000);
var aggregate3 = aggregate3Repo.Find(123);
aggregate1.DoSomeInternalWork();
firstService.DoWork(aggregate1.Id,aggregate2.Id);
secondService.DoWork(aggregate1.Id,aggregate3.Id);
aggregate1Repo.Update(aggregate1);
unitOfWork.Commit();
}
Run Code Online (Sandbox Code Playgroud)
Aggregate1Repo:
public class Aggregate1Repository
{
private readonly AppDBContext _dbContext;
private IMapper _mapper;
public Aggregate1Repository(AppDBContext context, IMapper mapper)
{
_dbContext = context; …Run Code Online (Sandbox Code Playgroud) c# domain-driven-design repository-pattern automapper asp.net-core
这是我在DDD上的第一次尝试,我想获得有关建模问题的建议。
这是我的专长:多所学校的管理。
2017-2018的实例)我的第一个疑问是对schoolYear的建模。
我已经将学校实体作为根集合。我的第一个方法是让学校聚合处理增加的schoolYear(这样我就可以避免重复,或者可以创建下一个schoolYear,……)
=> schoolYear是学校总数的一部分
但是后来我不得不对课程和学生分数进行建模……这取决于学校的年份。
因此,在我的所有班级中,我必须保留对schoolYear的引用……这违反了规定
“无法从外部汇总中引用内部实体。”
在我的领域中,很多实体都取决于特定的SchoolYear。也许应该是一个汇总……
另一方面,给定班级的schoolYear用于搜索班级。
我可以获取有关此建模问题的一些建议吗?
另一个有疑问的问题是关于schoolYear的身份。
有什么建议吗?
非常感谢您帮助我进入DDD世界!
c# ×3
cqrs ×3
aggregation ×1
architecture ×1
asp.net-core ×1
automapper ×1
entity ×1
events ×1
inheritance ×1
oop ×1
php ×1
reference ×1
rest ×1
rpc ×1