【发布时间】:2018-05-21 12:43:58
【问题描述】:
我在业务层上创建了一个基于Steven's answer 验证模型的结构。
它运行良好,但有些事情让我感到困惑。我在CreateUserValidator 中注入UserService 以便能够使用GetUser 方法。这意味着我在 UserService 中调用验证器并创建一个新的 UserService 实例来检查用户是否存在。
UserService -> [ValidateUser -> new 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;
}
}
【问题讨论】:
-
我想我最初的阅读似乎很愚蠢,因为您正在结合您的业务逻辑和数据层逻辑。 GetUser 方法可能应该在您的
_uow或等效项中,您也可以将其传递给您的验证器,而无需重新注入。此外,由于您只是检查是否正在使用电子邮件,因此就可读性而言,获取整个User可能不是最好的方法。也许考虑使用if(db.Users.Any(x=>x.Email == email)){return new Validation("Email In Use") -
我有基于 IGenericRepository 的 DAL 并处理
GetById等。但我认为我必须保持简单,像GetUserByEmail这样的特殊功能应该在业务层中。 -
注入并不总是必须在构造函数级别。也许
validate(CreateUser entity, IUserService userService)对您的情况更明智?服务将使用this作为第二个参数调用它。 -
@Andrei,好点子,由于 IValidationProvider 实现,我找不到用参数注入它的方法。我在做这个工作。 stackoverflow.com/questions/4776396/…
-
@ocanal,我认为在这种情况下不需要通过容器注入任何东西,只需直接将服务实例作为参数传递:
this._validationProvider.Validate(createUser, this);
标签: c# asp.net asp.net-mvc ninject ioc-container