【发布时间】:2019-05-18 20:22:40
【问题描述】:
我有一个 .NET Core Web Api 应用程序,它按以下方式排列 -
- 注入业务服务的控制器层
- 注入工作单元的业务服务(与数据库交互)
- 业务服务也可能调用 FluentValidation 类
- FluentValidation 将注入工作单元以执行数据库检查(存在等)
这里说了这么多,只是一个例子。如果我想在系统中创建一个用户,我在“UsersController”内有一个名为“PostUser”的路由/方法。 “UsersController”注入“UserService”。 “UserService”有一个名为“CreateUser”的方法。所以在控制器的“PostUser”方法内部看起来像这样 -
var user = _userService.CreateUser(user);
现在在“CreateUser”方法内部看起来像这样 -
UserValidation validation = new UserValidation(UnitOfWork, DatabaseOperation.Create);
ValidationResult validationResult = await validation.ValidateAsync(user);
因此,UnitOfWork 通过依赖注入传递给 UserService,然后传递给 FluentValidation 类“UserValidation”,因此验证类可以执行数据库检查。我还将一个枚举传递给 UserValidation 类,以指定验证是针对更新还是针对创建。
我尝试验证的用户对象将具有诸如“角色”和“公司”之类的属性,并且我还为每个对象设置了单独的验证类(RoleValidation 和 CompanyValidation)。这两个验证类也将传入 UnitOfWork 以及这是创建还是更新。
这是我的 UserValidation 类的示例 -
public class UserValidation : AbstractValidator<UserDTO>
{
private IUnitOfWork _unitOfWork;
public UserValidation(IUnitOfWork unitOfWork, DatabaseOperation databaseOperation)
{
_unitOfWork = unitOfWork;
if (databaseOperation == DatabaseOperation.Create)
{
// Do Create specific validation
}
RuleFor(x => x.Company)
.SetValidator(new CompanyValidator(_unitOfWork, databaseOperation));
}
}
现在了解了所有这些,我想为我的“UserService”类创建单元测试。但我相信为了正确地做到这一点,在某些情况下我需要模拟 FluentValidation 类,正如您在我的“UserService”CreateUser 方法中看到的那样,我为我的验证实例化了具体类。因此,为了做到这一点,我必须为我的每个 fluentvalidation 类创建一个接口,并将它们注入到使用它们的业务服务中。所以我在我的 Startup.cs 文件中做了以下操作 -
services.AddScoped<IValidator<User>>(x => new UserValidation(x.GetRequiredService<IUnitOfWork>()));
所以现在在这样做之后,我可以将 IValidator 注入到我的 UserService 构造函数中并使用它,而不是在我的 UserService 方法中实例化一个具体类。
因此,我提出以下问题。
- 在您看来,我已经构建项目的方式是使用 FluentValidation 的依赖注入并允许对服务方法进行单元测试以及 FluentValidation 类的单元测试的最佳方式吗?
- 有没有更好的方法使用依赖注入和 FluentValidation 来完成所有这些,同时让 FluentValidation 类知道它是“创建”还是“更新”,而不是创建一个名为“UserCreateValidation”的类" 和 "UserUpdateValidation" 还是将变量 "DatabaseOperation" 传递给 Validator 的构造函数?
- 尝试设置 FluentValidation DependencyInjection 时附加到 (2) 我无法传递“DatabaseOperation”变量
services.AddScoped<IValidator<User>>(x => new UserValidation(x.GetRequiredService<IUnitOfWork>(), <How to figure out if its a create or an update>)); - 除此之外,我还必须在“Startup.cs”文件中添加两行,以创建“CompanyValidation”和“RoleValidation”的Scoped DependencyInjection,以便在“UserValidation”和两者中使用无论是更新还是创建,这些验证类也会传入。
任何帮助/建议将不胜感激。我真的被这个问题困住了。如果有人需要进一步澄清我所面临的问题,请随时提出。
谢谢
【问题讨论】:
标签: c# .net-core dependency-injection fluentvalidation