我已经搜索了答案,甚至就这个问题提出了几个问题,但还没找到正确的答案。如何将POCO域对象和服务中的验证方法公开给UI层?目前我正在使用网络表单。
例如,我有以下域对象:
class Person
{
public string Name { get; set; }
public string Email { get; set; }
public bool IsValidEmail(string email) {}
public bool IsValidName(string name) {}
public bool IsValidPerson()
{
if (IsValidEmail(Email) && IsValidName(Name)) { return true; }
return false;
}
}
和域名服务:
class PersonService
{
private Person person;
private PersonRepository pRepo;
public PersonService()
{
person = new Person();
pRepo = new PersonRepository();
}
public AddPerson(Person p)
{
if (p.IsValidEmail(p.Email) && p.IsValidName(p.Name) && !DoesEmailExistInDatabase(p.Email))
{ pRepo.Save(p); }
else
{ throw new ArgumentException(); }
}
public GetPersonByEmail(string email)
{
if (person.IsValidEmail(Email))
{ pRepo.GetByEmail(email)); }
else
{ throw new ArgumentException(); }
}
public bool DoesEmailExistInDatabase(string email) { //code if exists.. }
}
和UI / Codebehind图层:
通过电子邮件获取此人
string emailInput = EmailTextBox.Text;
PersonService pService = new PersonService();
Person p = new Person();
if(p.IsValidEmail(emailInput))
{
Person myPerson = pService.GetPersonByEmail(emailInput);
}
else
{
//give user error here...
}
为域对象中可能需要验证的每个属性创建单独的验证方法是否正确?
域对象和服务中的那些方法是否应该是静态的,所以我不必创建人员实例来进行验证?
我是否应该公开服务中Person域对象的验证,这样用户就不需要知道在哪里查找它们了(因为我把一些服务器放在了POCO中的原因是真的一个实施问题)?
4.有更好的方法吗?
答案 0 :(得分:2)
Re#1 - 是(这是一种有效的方法),假设域对象最适合“知道”正确的输入是什么。
Re#2 - 是的。
Re#3 - 这样做没有坏处,但是,如果你不相信课外的东西能够/负责实际的验证,你为什么会相信它来调用验证呢?
我会在设置值时强制执行验证,一旦在对象中有“好数据”,就不需要稍后验证它。这导致了第4点......
Re#4 - 以某种方式提供/暴露验证的奖励是系统的其他部分可以使用它;经典的例子是在UI中,您可以通过验证输入或提交的输入来提供更好的用户体验。
另一种验证方法是确定哪些好的数据(在整体视图中) - 并为那些作为(单独的)公共域级“服务”存在的规则定义一堆规则。验证每个域对象内部的输入是好的,因为随着时间的推移,您可以更改特定规则,因为单个域对象会随着时间的推移而成熟(您可以限制隔离更改的影响) - 缺点是您将重复许多规则。
一个常见的服务可以解决这个问题,一个服务会说“这就是一个有效的电子邮件地址”,你的所有域对象都会推迟服务,告诉他们一个好的电子邮件地址是什么。
这种方法的“技巧”是要小心你如何命名验证方法 - 不要太模糊或含糊不清。例如,您可能会发现大多数具有电子邮件属性的域对象使用一种“主”电子邮件验证方法ValidateGenericEmail()
的情况,但您经常会遇到其他对象是具有特殊规则的特殊情况的情况{{ 1}}。没关系,将它们添加到验证服务中,因为这是域层中用于管理这些规则的中心位置。
您的域对象仍然可以执行之前需要他们执行的所有操作 - 除非您已将规则撤回到单独的公共位置。
答案 1 :(得分:0)
我只在表示层和清理域模型上保持验证。因此,域模型假定数据已经过验证(并且已经过验证,不是吗?)。或者你有另一个数据源可以来自哪里? 这将使您的域模型更加纯粹,您将看到它的核心。但是通过使用guard子句检查构造函数参数,在对象的创建时强制执行一些约束是不错的。