2011-12-30 85 views
2

我正在寻找关于如何构建验证服务层的教程。我希望该图层存在于我的“域”组合中。目前我已经有了我的域模型和(可能不是最好的)通用存储库实现。构建验证服务层

我的仓库实现旁边:

public sealed class Repository<T> : Interface.IRepository<T> where T : Entity<T> 
{ 
    private ISessionFactory sessionFactory;   

    public Repository(ISessionFactory sessionFactory) 
    {      
     this.sessionFactory = sessionFactory; 
    } 

    public T Get(Guid id) 
    { 
     using(var session = this.sessionFactory.OpenSession()) 
     { 
      return session.Get<T>(id); 
     } 
    } 
    public IQueryable<T> Get(Expression<Func<T, Boolean>> predicate) 
    { 
     using(var session = this.sessionFactory.OpenSession()) 
     { 
      return session.Query<T>().Where(predicate); 
     } 
    } 
    public IQueryable<T> All() 
    { 
     using(var session = this.sessionFactory.OpenSession()) 
     { 
      return session.Query<T>(); 
     } 
    } 
    public void Add(T entity) 
    { 
     // execute validation here? 

     using(var session = this.sessionFactory.OpenSession()) 
     using(var transaction = session.BeginTransaction()) 
     { 
      session.Save(entity); 
      transaction.Commit(); 
     } 
    } 
    public void Remove(T entity) 
    { 
     using(var session = this.sessionFactory.OpenSession()) 
     using(var transaction = session.BeginTransaction()) 
     { 
      session.Delete(entity); 
      transaction.Commit(); 
     } 
    } 
    public void Update(T entity) 
    { 
     // make changes & 
     // execute validation here? 

     using(var session = this.sessionFactory.OpenSession()) 
     using(var transaction = session.BeginTransaction()) 
     {     
      session.Update(entity); 
      transaction.Commit(); 
     } 
    } 
} 

我想用FluentValidation验证实体。据我了解,在仓库范围内,只有两个地方需要进行验证:添加和更新实体时。

首先,我认为把IValidator<T>作为参数传递给基础机构类:

public abstract class Entity<T> where T : Entity<T> 
{ 
    // ...   
    public virtual String ValidationMessage 
    { 
     get; 
     private set; 
    } 

    public virtual Boolean Validate(IValidator<T> validator) 
    { 
     try 
     { 
      validator.ValidateAndThrow(this as T); 
      return true; 
     } 
     catch(ValidationException ex) 
     { 
      this.ValidationMessage = ex.Message; 
      return false; 
     } 
    } 
    // ...  
} 

但它似乎并不正确。

从设计的角度来看,我该如何做到这一点?任何意见或教程表示赞赏。

谢谢!

回答

0

恕我直言,问题很大程度上取决于你到达存储库。事情是,你允许创建一个无效的域对象,现在你需要验证它,以确保你不坚持它,除非它的不变满足。

除了技术方面,这在你正在做的事情的概念层面上有更深的含义。 请记住,一个对象建模现实世界的一个实体:比如说一个人有一个负的年龄是否有意义?我们都会同意没有人存在负面年龄,因此记住现实世界和软件之间的映射关系,我们可以看到,没有Person对象应该存在负的年龄,因为该模型在世界上没有其对应物。

回想一下你的场景,想一想关于存​​储库的一段时间:它是否适合实体验证的责任?这似乎远比仓库应该做的更多。

我喜欢做的是在构建域对象之前验证构成域对象的所有参数。通过这种方式,我确信如果对象被实例化了,那么它肯定是有效的。无论何时将消息发送到会导致状态更改的对象,您都可以这样做。

有关验证,你有一些选择:

  • 通过验证类的实例对象的构造函数。每次你需要验证它时,都会觉得不合适,因为这意味着可能有多个类将具有用于验证的正确IValidator<T>的知识。
  • 有一个类负责为您构建对象:使您的构造函数保持私有状态,并使用静态创建方法来实现正确的实例化。

这一切都取决于验证需要多复杂。无论哪种方式,您都需要封装该决策,以便它不会遍布整个代码库(仅在一个地方实例化一个域对象)。