我的应用程序大量使用预订窗口,所以我有一个规范,确保即将添加到聚合的预订窗口不会与当前聚合的另一个窗口重叠.如下所示.
/// <summary>/// A specification that determines if the window passed in collIDes with other windows./// </summary>public class BookingTemplateWindowDoesNotCollIDeSpecification : ISpecification<BookingScheduleTemplateWindow>{ /// <summary> /// The other windows to check the passed in window against. /// </summary> private Readonly IEnumerable<BookingScheduleTemplateWindow> otherwindows; /// <summary> /// Initializes a new instance of the <see cref="BookingTemplateWindowDoesNotCollIDeSpecification" /> class. /// </summary> /// <param name="otherwindows">The other windows.</param> public BookingTemplateWindowDoesNotCollIDeSpecification(IEnumerable<BookingScheduleTemplateWindow> otherwindows) { this.otherwindows = otherwindows; } /// <summary> /// Determines whether the window passed in collIDes with other windows held insIDe this class. /// </summary> /// <param name="obj">The obj.</param> /// <returns> /// <c>true</c> if [is satisfIEd by] [the specifIEd obj]; otherwise,<c>false</c>. /// </returns> public bool IsSatisfIEdBy(BookingScheduleTemplateWindow obj) { return !this.otherwindows.Any(w => obj.DayOfWeek == w.DayOfWeek && w.WindowPeriod.IsOverlap(obj.WindowPeriod)); }}
然后我在聚合上有一个方法,允许使用规范添加一个新窗口.已经持久化的聚合窗口被传递到规范构造函数中.
public virtual voID AdDWindow(DayOfWeek dayOfWeek,int startTime,int endTime) { var nonCollIDingwindowspecification = new BookingTemplateWindowDoesNotCollIDeSpecification(this.windows); var bookingWindow = new BookingScheduleTemplateWindow(this){ DayOfWeek = dayOfWeek,WindowPeriod = new Range<int>(startTime,endTime) }; if (nonCollIDingwindowspecification.IsSatisfIEdBy(bookingWindow)) { this.windows.Add(bookingWindow); } }
我正在努力的是,我的一部分是认为我应该将这个规范注入到类中而不是直接实例化(作为我的应用程序的一般规则,而不仅仅是在这种情况下),因为可能需要这种类型的specfication根据实体的状态进行更改.但是从MVC层注入规范感觉很脏,好像我有一个像REST API这样的另一个应用程序接口,然后关于使用哪个规范的逻辑将被复制.
如何确保所使用的规范保持灵活性,同时确保使用哪个规范的逻辑不会在另一个应用程序界面中重复.
这是一种情况,您希望将工厂注入实体并从那里返回规范,从而不允许域逻辑溢出到更高层?或者有更好/更清洁/更简单的方法吗?
解决方法 将域服务注入实体是完全可以接受的.最好将服务的依赖关系显式化为聚合中相应方法中的参数.例如,AdDWindow方法可能如下所示:public virtual voID AdDWindow(ISpecification<BookingScheduleTemplateWindow> nonCollIDingwindowspecification,DayOfWeek dayOfWeek,int endTime) { var bookingWindow = new BookingScheduleTemplateWindow(this){ DayOfWeek = dayOfWeek,endTime) }; if (nonCollIDingwindowspecification.IsSatisfIEdBy(bookingWindow)) { this.windows.Add(bookingWindow); } }
在这种情况下,规范充当域服务.现在,周围的基础设施需要通过适当的规范.这就是应用程序服务的用武之地.应用程序服务在您的域层上建立了一个外观,并包含特定用例的方法.反过来,该应用程序服务将由控制器引用.控制器也可以传递所需的依赖关系,但是应用程序服务提供的封装可能是有益的.
示例应用服务代码:
public class AdDWindow(string aggregateID,int endTime){ var aggregate = this.repository.Get(aggregateID); var specification = // instantiate specification aggregate.AdDWindow(specification,dayOfWeek,startTime,endTime); this.repository.Commit();}
这是典型的应用程序服务代码:获取适当的聚合,实例化所需的依赖项(如果有),并在聚合上调用行为.
总结以上是内存溢出为你收集整理的域驱动设计 – 在域驱动设计中正确使用规范类全部内容,希望文章能够帮你解决域驱动设计 – 在域驱动设计中正确使用规范类所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)