我正在寻找有关如何构建验证服务层的教程。我想让图层出现在我的'domain'程序集中。目前我已经拥有了我的域模型和(可能不是最好的)通用存储库实现。
我的存储库实现是下一步:
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 :(得分:0)
除了技术方面,这对你正在做的事情的概念层面有更深刻的影响。 请记住,一个物体模拟现实世界的一个实体:例如,一个人有一个负面年龄是否有意义?我们都同意没有人存在负面年龄,因此记住现实世界和软件之间的映射,我们可以看到没有Person对象应该存在负年龄,因为该模型在世界上没有它的对应物
回到您的场景,想一想存储库:它是否适合实体验证的责任?这似乎远不是存储库应该做的。
我喜欢做的是在创建域对象之前验证构成域对象的所有参数。通过这种方式,我确保,如果对象被实例化,那么它必须是有效的。每当将消息发送到将导致其状态发生变化的对象时,您都可以这样做。
关于验证,您有一些选择:
IValidator<T>
。这完全取决于验证需要多复杂。无论哪种方式,您都希望封装该决策,以便它不会遍布您的代码库(仅在一个地方实例化一个域对象)。