C# 将DbContext或repository注入到fluent验证验证器中是一种好的做法吗

C# 将DbContext或repository注入到fluent验证验证器中是一种好的做法吗,c#,validation,dependency-injection,fluentvalidation,C#,Validation,Dependency Injection,Fluentvalidation,你对这个想法有什么看法: 一些DTO需要涉及数据库交互的验证,因此我们将DbContext或repository类插入到validator类中,并使用它进行验证 public class UserEditSelfResourceValidator : AbstractValidator<UserEditSelfResource> { private IUserRepository _userRepository; public Use

你对这个想法有什么看法: 一些DTO需要涉及数据库交互的验证,因此我们将DbContext或repository类插入到validator类中,并使用它进行验证

    public class UserEditSelfResourceValidator : AbstractValidator<UserEditSelfResource>
    {
        private IUserRepository _userRepository;

        public UserEditSelfResourceValidator(IUserRepository userRepository, ILoggedInUserService loggedInUser)
        {
            _userRepository = userRepository;
            RuleFor(mem => mem.ProfileUrl).MustAsync(async (entity, value, c) => await UniqueProfileUrl(entity, value))
                .WithMessage("Profile Url must be unique.");

        }

        public async Task<bool> UniqueProfileUrl(UserEditSelfResource userEditSelf, string newProfileUrl)
        {
            var user = await _userRepository.FindByProfileUrlAsync(newProfileUrl);
            
            if(user.Id == _loggedInUser.GetId() || user == null)
            {
                return true;
            }
            return false;
        }
    }
公共类UserEditSelfResourceValidator:AbstractValidator
{
专用IUserRepository\u用户存储库;
公共UserEditSelfResourceValidator(IUserRepository userRepository,ILoggedInUserService loggedInUser)
{
_userRepository=userRepository;
RuleFor(mem=>mem.ProfileUrl).MustAsync(async(实体,值,c)=>await UniqueProfileUrl(实体,值))
.WithMessage(“配置文件Url必须唯一”);
}
公共异步任务UniqueProfileUrl(UserEditSelfResource userEditSelf,字符串newProfileUrl)
{
var user=await\u userRepository.findbyprofileurlsync(newProfileUrl);
if(user.Id==_loggedInUser.GetId()|| user==null)
{
返回true;
}
返回false;
}
}

你认为这样的想法是一个好的做法还是有什么不对的?

< P>我相信这是一个非常直接的答案:从10000英尺的角度来看,你所做的看起来很好。 我之所以这样说,是因为你把你的验证放在一个地方。由于DbContext将被注入,因此每次需要执行此特定验证时,对数据库的单独和重复调用不会污染代码

    public class UserEditSelfResourceValidator : AbstractValidator<UserEditSelfResource>
    {
        private IUserRepository _userRepository;

        public UserEditSelfResourceValidator(IUserRepository userRepository, ILoggedInUserService loggedInUser)
        {
            _userRepository = userRepository;
            RuleFor(mem => mem.ProfileUrl).MustAsync(async (entity, value, c) => await UniqueProfileUrl(entity, value))
                .WithMessage("Profile Url must be unique.");

        }

        public async Task<bool> UniqueProfileUrl(UserEditSelfResource userEditSelf, string newProfileUrl)
        {
            var user = await _userRepository.FindByProfileUrlAsync(newProfileUrl);
            
            if(user.Id == _loggedInUser.GetId() || user == null)
            {
                return true;
            }
            return false;
        }
    }
只要您的数据库调用只使用处理任何给定的特定验证任务所需的最小值(您不希望仅为了选择一个属性而返回整个对象),您就可以将关注点分开。我假设您将把验证服务注入控制器之类的地方


这只是个人偏好,但我认为经验法则是,“如果下一个人需要在没有任何直接解释的情况下继续我的话,这对他或她来说是否容易理解?”将您的关注点分开(例如您尝试实现的验证服务)这意味着,如果我需要对验证进行修复或更改,我确切地知道要去的地方,并且我不必对其他所有事情都知道太多,比如什么是消费服务。我所需要的一切都在那一个地方。

我相信这是一个非常直截了当的答案:从10000英尺的角度来看,你所做的看起来很好

我之所以这样说,是因为你把你的验证放在一个地方。由于DbContext将被注入,因此每次需要执行此特定验证时,对数据库的单独和重复调用不会污染代码

    public class UserEditSelfResourceValidator : AbstractValidator<UserEditSelfResource>
    {
        private IUserRepository _userRepository;

        public UserEditSelfResourceValidator(IUserRepository userRepository, ILoggedInUserService loggedInUser)
        {
            _userRepository = userRepository;
            RuleFor(mem => mem.ProfileUrl).MustAsync(async (entity, value, c) => await UniqueProfileUrl(entity, value))
                .WithMessage("Profile Url must be unique.");

        }

        public async Task<bool> UniqueProfileUrl(UserEditSelfResource userEditSelf, string newProfileUrl)
        {
            var user = await _userRepository.FindByProfileUrlAsync(newProfileUrl);
            
            if(user.Id == _loggedInUser.GetId() || user == null)
            {
                return true;
            }
            return false;
        }
    }
只要您的数据库调用只使用处理任何给定的特定验证任务所需的最小值(您不希望仅为了选择一个属性而返回整个对象),您就可以将关注点分开。我假设您将把验证服务注入控制器之类的地方

这只是个人偏好,但我认为经验法则是,“如果下一个人需要在没有任何直接解释的情况下继续我的话,这对他或她来说是否容易理解?”将您的关注点分开(例如您尝试实现的验证服务)这意味着,如果我需要对验证进行修复或更改,我确切地知道要去的地方,并且我不必对其他所有事情都知道太多,比如什么是消费服务。我需要的一切就在那一个地方