【发布时间】:2016-07-04 12:47:48
【问题描述】:
我有一个 MVC 应用程序,其中域模型(数据模型 + 业务模型)驻留在不同的类库中。我使用的接口公开了一些必须返回数据但不一定是我的域对象的整个表示的方法。
我的问题是我应该如何返回数据?
我应该在业务模型层上创建一种视图模型,然后将它们与我在主应用程序上的真实视图模型(views-controllers-viewmodels)匹配吗?
我应该将此数据作为动态对象返回吗?
我应该返回整个域对象事件吗?我只需要几个属性吗?
最好的方法是什么?
这是一个更好地了解情况的示例:
//Domain Class
public class User
{
public string UserName { get; set; }
public int UserId { get; set; }
public string UserPassword{ get; set; }
public string FirstName{ get; set; }
public virtual ICollection<ApplicationUserTeam> ApplicationUserTeams
{
get { return _applicationUserTeams; }
set { _applicationUserTeams = value; }
}
}
public interface ITrackAttendance
{
dynamic GetUsersCompany(int CompanyId);
}
public class TrackAttendanceServices : ITrackAttendance
{
//Method returning a Dynamic Object???
public dynamic GetUsersCompany(int CompanyId)
{
using (var _ctx = new TrackAttendanceDb())
{
return _ctx.Users.Where(u => u.ApplicationUserTeams.FirstOrDefault().Team.CompanyId== CompanyId)
.Select(u =>
new
{
UserName = u.UserName,
UserId = u.Id,
userState = false
}).ToList();
}
}
}
项目架构:
我的解决方案:
感谢所有对此问题发表意见的专家,我决定基于以下几个方面采用 DTO 方法 (@uk2k05):
- 它让我能够保持一个非常干净的架构。
- 这种方式更符合单一职责原则
- 它确保我的应用层不依赖于底层域模型。
我必须承认这里提出的其他有趣的方法,例如工厂模式 (@Liam) 和命令查询分离 (CQS)(@L-Four),它们都有助于解决问题,但它们可能会为我的特定环境增加额外的复杂性和工作。 CQS 和 FP 需要转变思维来定义架构(根据我的拙见和个人意见)。
【问题讨论】:
-
为什么要返回域模型实体进行查询?为什么不将命令与查询分开,直接绕过领域层进行查询。
-
对不起,我不是你的意思。你能更明确一点或者举个例子吗?谢谢。
-
我认为Factory pattern 可以更好地解决您在这里尝试做的事情。你创建了一个工厂,你调用工厂返回一个对象。您在控制器中使用此对象(可能根据实现转换为 ViewModel)。那就是说你的问题很不清楚。例如,这其中的哪一部分应该是存储库模式?
-
好吧,伙计们,我有点困惑,基本上我试图避免将我的对象暴露给应用程序层(不在此处创建对该库的引用),同时,不复制我的业务在域层中创建一种“视图模型”的对象(我猜这个 DTO 定义)在我看来有点多余。只想知道如何将部分实体返回给控制器(无需从控制器查询数据库)。
-
感谢@Liam,使用工厂模式显然有很好的理由。但是,与 CQS 原则一样,我还看不到要应用的正确环境。由于我更新的问题中暴露的原因,我决定坚持使用 DTS 方法。 (PS:@Liam,可惜你删了你的第一个答案,真的很有用。)
标签: c# asp.net-mvc design-patterns model-view-controller repository-pattern