业务层验证:如何调用服务方法?

时间:2017-12-07 11:53:54

标签: c# asp.net asp.net-mvc ninject ioc-container

我创建了一个关于在Business Layer上验证模型的结构,该结构基于Steven's answer

它运作良好,但有些让我困惑的事情。我在UserService中注入CreateUserValidator以便能够使用GetUser方法。这意味着我在UserService中调用验证器并创建一个新的UserService实例来检查用户是否存在。

  

UserService - > [ValidateUser - >新的UserService()。GetUser()]

它可行,但似乎是一个非常糟糕的设计。但我必须使用那种方法。

请您告诉我如何解决这个问题,或者我不应该担心吗?

public class CreateUser
{
    public string Name { get; set; }
    public string Email { get; set; }
}

public sealed class CreateUserValidator : Validator<CreateUser>
{
    private IUserService _userService;
    public CreateUserValidator(IUserService userService)
    {
        _userService = userService;
    }
    protected override IEnumerable<ValidationResult> Validate(
        CreateUser entity)
    {

        var user = _userService.GetUserByEmail(entity.Email);
        if (user != null)
        {
            yield return new ValidationResult("Email", "Email address is already exist!");
        }
    }
}

UserService.cs

public partial class UserService : IUserService
{
    IGenericUnitofWork _uow = null;
    private readonly IValidationProvider _validationProvider;
    public UserService(IGenericUnitofWork uow, IValidationProvider validationProvider)
    {
        _uow = uow;
        _validationProvider = validationProvider;
    }

    public User CreateUser(CreateUser createUser)
    {
        this._validationProvider.Validate(createUser);

        var user = new User()
        {
            Email = createUser.Email,
            Name = createUser.Name,
        };
        _uow.Repository<User>().Insert(User);
        _uow.SaveChanges();
        return user;
    }

    public User GetUser(string email)
    {
        var user = _uow.Repository<User>().Where(m => m.Email == email).FirstOrDefault();
        return user;
    }
}

1 个答案:

答案 0 :(得分:2)

依赖图是循环的。正如section 6.3Dependency Injection in .NET second edition中所述,依赖性周期通常是由Single Responsibility Principle违规引起的,就像您的设计中的情况一样。

问题在于UserService有太多责任:创建用户与获取用户的责任不同。创建用户可能会成为一个非常复杂的用例,正如验证逻辑所暗示的那样,而获取用户通常非常简单。因此,将UserService拆分为多个较小的类是有益的。这将允许验证器依赖于允许通过其邮件地址检索用户的服务,同时创建用户&#39;服务可以取决于验证器。

为了更进一步,您可能希望从“创建用户”中删除验证。完全服务。验证是一个贯穿各领域的问题,并将其与包含业务逻辑的类混合在一起,使得这类更难维护。

可能使您受益的设计是将所有状态更改业务操作置于公共抽象之后的设计,如here所述。