我已经搜索了答案,甚至问了几个与此主题有关的问题,但还没有真正找到正确的答案。如何在POCO Domain对象和服务中向UI层公开验证方法?目前,我正在使用Web表单。

例如,我有以下域对象:

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的实例?
我是否应该在Service中公开来自Person域对象的验证,以便用户不需要知道在哪里寻找它们(因为我将某些服务投入使用,而将某些POCO投入的原因实际上是实现问题)?


4.有更好的方法吗?

最佳答案

关于#1-是的(这是一种有效方法),前提是假定域对象最适合“知道”什么是正确的输入。

关于#2-是的。

关于#3-这样做没有什么害处,但是,如果您不信任类外部的某些事物能够/负责进行实际的验证,那么为什么您会信任它调用验证呢?

设置值后,我将强制执行验证,一旦对象中具有“良好的数据”,以后就无需验证。这导致第4点...

关于#4-以某种方式提供/公开验证的好处是系统的其他部分可以使用它;经典示例在UI上,您可以通过验证输入或提交的输入来提供更好的用户体验。

验证的另一种方法是(从总体上看)确定什么样的好数据-并为作为(单独的)公共域级“服务”而存在的规则定义一堆规则。验证每个域对象内部的输入是不错的选择,因为随着各个域对象随着时间的推移逐渐成熟(可以限制孤立更改的影响),您可以更改特定的规则-缺点是您将重复很多规则。

普通的服务可以解决此问题,服务会说“这是有效的电子邮件地址的样子”,您所有的域对象都将服从该服务以告诉他们什么是好的电子邮件地址。

这种方法的“技巧”是要小心命名验证方法的方式-不要太含糊或模棱两可。例如,您可能会发现大多数具有电子邮件属性的域对象都使用一种“主要”电子邮件验证方法ValidateGenericEmail(),但您经常会遇到其他对象是具有特殊规则ValidateCorporateEmail()的特殊情况的情况。可以,将它们添加到验证服务中,因为这是管理这些规则的域层的中心位置。

然后,您的域对象仍然可以执行您需要他们做的所有事情-除了将规则拉到一个单独的公用位置之外。

08-04 17:34