目前正在深入研究DDD,我已经阅读了Eric Evans的大部分蓝皮书。到目前为止非常有趣:)
我一直在为一些聚合建模,在这些聚合中他们拥有一系列过期的实体。我想出了一种表达的通用方法:
public class Expirable<T>
{
public T Value { get; protected set; }
public DateTime ValidTill { get; protected set; }
public Expirable(T value, DateTime validTill)
{
Value = value;
ValidTill = validTill;
}
}
我很好奇最好的方法是使Expirable无效(在集合中工作时无效或省略它)。到目前为止,我一直在考虑在Repository构造函数中执行此操作,因为这是您从中访问聚合的位置,并充当“集合”。
我很好奇是否有人提出解决方案来解决这个问题,我很乐意听到它:)其他方法也非常受欢迎。
更新10-1-2013:
这不是来自Greg Young的CQRS / ES方法的DDD。但是埃文斯的方法,因为我刚开始使用这本书和第一个应用程序。就像Greg Young说的那样,如果你必须做好桌子,你必须先做一些;)
答案 0 :(得分:1)
可能有多种方法可以解决这个问题,但我个人会使用规范模式来解决这个问题。假设对象到期是属于域的业务规则,除了您编写的类之外,我还有一个规范。这是一个例子:
public class NotExpiredSpecification
{
public bool IsSatisfiedBy(Expirable<T> expirableValue)
{
//Return true if not expired; otherwise, false.
}
}
然后,当您的存储库返回聚合列表或在集合上执行任何业务操作时,可以利用此限制将集合限制为未过期的值,这将使您的代码具有表现力并将业务逻辑保留在域。
要详细了解规范模式,请参阅this paper。
答案 1 :(得分:0)
我在我的抽象存储库InvalidateExpirable
中添加了一个方法。一个示例是UserRepository
我在活动用户会话中删除的内容如下:InvalidateExpirable(x => x.Sessions, (user, expiredSession) => user.RemoveSession(expiredSession));
。
InvalidateExpirable
的签名如下所示:protected void InvalidateExpirable<TExpirableValue>(Expression<Func<T, IEnumerable<Expirable<TExpirableValue>>>> selector, Action<T, Expirable<TExpirableValue>> remover)
。该方法本身使用反射从selector参数中提取selected属性。该属性名称粘贴在一个通用的HQL查询中,该查询将遍历调用remove lambda的集合。 user.RemoveSession
将从聚合中删除会话。这样我保持聚合对它自己的数据负责。同样在RemoveSession
中,将针对未来案例引发域事件。
请参阅:https://gist.github.com/4484261以获取示例
非常好用,我必须看看它在应用程序中的工作原理如何。
答案 2 :(得分:0)
一直在阅读使用CQRS / ES(Greg Young方法)的DDD,并在MSDN网站上找到了关于CQRS / ES的一个很好的例子:http://msdn.microsoft.com/en-us/library/jj554200.aspx
在此示例中,他们使用命令消息队列在将来对Expire消息进行排队,该消息将在指定时间调用Aggregate从聚合中删除/停用可过期构造。