构建验证服务层

本文关键字:服务 验证 构建 | 更新日期: 2023-09-27 18:19:09

我正在寻找如何构建验证服务层的教程。我希望这个层出现在我的"域"组装中。目前,我已经得到了我的领域模型和(可能不是最好的)通用存储库实现。

我的存储库实现是下一个:

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;
        }
    } 
    // ...      
} 

但这似乎不对。

从设计的角度来看,我如何做到这一点?任何建议或指导都是感激的。

谢谢!

构建验证服务层

恕我直言,问题在到达存储库之前就存在了。问题是,在某个地方你允许创建一个无效的域对象,现在你需要验证它,以确保你不会持久化它,除非它的不变量是满足的。

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

回到您的场景,考虑一下存储库:它是否适合其中的实体验证责任?这似乎远远超过了存储库应该做的。

我喜欢做的是在创建域对象之前验证组成域对象的所有参数。通过这种方式,我可以确保,如果对象被实例化,那么它必须是有效的对象。当一个消息被发送到一个对象,将导致其状态改变时,你也可以这样做。

关于验证,您有一些选择:

  • 传递验证类的实例给对象的构造函数。每次你需要验证它的时候,让它传递是不对的,因为这意味着可能不止一个类将知道正确的IValidator<T>用于验证。
  • 有一个类负责为你构建对象:使你的构造函数私有,并使用静态创建方法来完成正确的实例化。

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