【发布时间】:2011-07-04 09:51:28
【问题描述】:
我正在尝试了解和找出设计应用/域模型 (POCO/DTO) 的良好做法。
假设我有以下数据库表,帐户:
UserID int
Email varchar(50)
PasswordHash varchar(250)
PasswordSalt varchar(250)
当然,EF4 会像这样构建实体:
public class Account
{
public int UserID { get; set; }
public string Email { get; set; }
public string PasswordHash { get; set; }
public string PasswordSalt { get; set; }
}
现在,假设我有一个用于注册新用户的视图模型,它可能看起来像这样:
public class RegistrationViewModel
{
public string Email { get; set; }
public string Password { get; set; }
}
最后,我有一个需要注册用户的服务:
public class RegistrationService
{
public void RegisterUser(??? registration)
{
// Do stuff to register user
}
}
我正在尝试找出要传递给 RegisterUser 方法的内容。视图模型当然位于我的 Web 应用程序(表示层)下,所以我不希望它被传递给我的服务。
所以,我在考虑以下四种可能性之一:
1) 设置一个与 RegistrationViewModel 相似(如果不相同)的服务模型,并使用它:
public class RegistrationServiceModel
{
public string Email { get; set; }
public string Password { get; set; }
}
public class RegistrationService
{
public void RegisterUser(RegistrationServiceModel registration)
{
// Do stuff to register user
}
}
2)设置模型的接口,并在我的视图模型中继承这个,并设置我的方法接受接口:
public interface IRegistrationModel
{
string Email;
string Password;
}
public class RegistrationServiceModel : IRegistrationModel
{
public string Email { get; set; }
public string Password { get; set; }
}
public class RegistrationService
{
public void RegisterUser(IRegistrationModel registration)
{
// Do stuff to register user
}
}
3) 传入 Account 实体,在我的控制器中进行 RegistrationViewModel 到 Account 的映射:
public class RegistrationService
{
public void RegisterUser(Account account)
{
// Do stuff to register user
}
}
4) 将我的视图模型从表示中移到域/服务层,并将其传递给服务方法:
public class RegistrationService
{
public void RegisterUser(RegistrationViewModel account)
{
// Do stuff to register user
}
}
这三种情况似乎都不理想,因为我发现每种情况都存在问题。所以我想知道是否还有其他我想不到的方法。
对此有什么好的做法?
提前致谢。
【问题讨论】:
-
顺便说一句,杰拉德,你认为第三种情况到底是什么问题?
-
@Vasilio Ruzanni - 我的问题(以及我听到其他人所说的)与该选项是您的服务/业务层与您的数据模型(EF4 实体)紧密耦合,这可能会改变比业务/领域模型更频繁(抱歉混合术语,我仍然不了解这些差异)。
-
好吧,我看到了您的问题,您正在尝试解决“可能出现但不存在”的问题。您总是必须在复杂性和可用性之间做出平衡。当然,您的
RegistrationModel方法将所有内容抽象出来,但它不会使您的系统更易于维护(这是过度工程的威胁信号)。 -
要点,简短地说:不要过度设计,您的 EF 实体是您的域模型的 THE 核心!域服务也是您域的一部分。不要从域模型中隐藏域模型。如果您更改您的实体,您将必须更改服务,因为您的实体和服务在概念上是绑定的。因此,我认为
RegistrationService.RegisterUser(Account account, string password)方法是足够 的理想选择(是的,主要强调足够)。 -
@Vasilio - 谢谢,我慢慢明白你的意思了。我已经开始沿着这条路线走(使用 AutoMapper),这似乎是有道理的。感谢您的帮助!
标签: asp.net-mvc entity-framework viewmodel