c# - 使用简单注入(inject)器注册通用验证

标签 c# inversion-of-control fluentvalidation simple-injector

我想使用 SimpleInjector 注册通用验证( Fluent-validation )...

这是我迄今为止尝试过的:
User.cs:

public class User
{
    public int Id { get; set; }   
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

UserService.cs

public class UserService : IUserService
{
    private readonly IValidator<User> _userValidator;

    public UserService(IValidator<User> userValidator)
    {
        _userValidator = userValidator;
    }

    public OperationResult Add(User user)
    {
        OperationResult operationResult = new OperationResult();

        ValidationResult validationResult = _userValidator.Validate(user);
        if (!validationResult.IsValid)
        {
            operationResult.IsSuccess = false;

            ValidationFailure firstOrDefaultValidationFailure =
                validationResult.Errors.FirstOrDefault();

            if (firstOrDefaultValidationFailure != null)
            {
                operationResult.Message = firstOrDefaultValidationFailure.ErrorMessage;
            }
        }

        //TODO do your business here...

        return operationResult;
    }
}

国际奥委会:

    Container = new Container();

    // I WANT TO MAKE BELOW LINE GENERIC...
    Container.Register(typeof(IValidator<User>), () => new UserValidator());

    Container.Register<IUserService, UserService>(Lifestyle.Transient);

    Container.Verify();

现在正在运行。但正如您所看到的,验证器的注册不是通用的。

我试过了;

Container.Register(typeof(IValidator<>), typeof(ValidationContext<>));

运行时出现错误:

For the container to be able to create ValidationContext<T> it should have only one public constructor: it has 2

我也尝试过:

Container.Register(typeof(IValidator<>), typeof(ValidatorDescriptor<>));

另一个错误:

The supplied type ValidatorDescriptor<T> does not implement IValidator<T>

我上次尝试过:

IValidatorFactory validatorFactory = new AttributedValidatorFactory();
IValidator<User> validator = validatorFactory.GetValidator<User>();

但是它给出了 null 验证器。因为 User.cs 类上没有类似的属性;

[Validator(typeof(UserValidator))]

我该如何解决这个问题?

最佳答案

所以,如果我理解正确的话,你有 IValidator<T> 的多个非通用实现。 (例如 UserValidatorEmployeeValidatorOrderValidator 等)并且您想将它们全部注册。

这是文档 here 中描述的场景你基本上有两个选择。

选项 1:逐一注册它们:

container.Register<IValidator<User>, UserValidator>();
container.Register<IValidator<Customer>, CustomerValidator>();
container.Register<IValidator<Employee>, EmployeeValidator>();
container.Register<IValidator<Order>, OrderValidator>();
container.Register<IValidator<Product>, ProductValidator>();
// etc

选项 2:使用批量注册:

container.Register(typeof(IValidator<>), new[] { typeof(IValidator<>).Assembly });

这里我们传入一个包含程序集的列表,Simple Injector 使用该列表来搜索 IValidator<T> 的非通用实现。 。在内部,Simple Injector 将进行与我们使用选项 1 手动执行的相同的一组注册。

请注意,您的服务类与支持验证的代码纠缠在一起。这会导致大量代码重复,增加复杂性,并可能导致将来的维护问题。您应该考虑使用描述的命令转移到模型 here 。该模型允许在命令而不是实体上定义评估器,这允许定义单个通用装饰器,该装饰器允许将验证应用于业务逻辑。

关于c# - 使用简单注入(inject)器注册通用验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36343642/

相关文章:

c# - 通过 Interop/pinvoke 传递 C# 回调函数

c# - ASP.NET Core 2.0 - 提供没有扩展名的文件

c# - 如何在 C# 程序和 Node.js 程序之间使用 Msgpack?

C# 当我使用 reflect 注册类时,为什么不能从 ioc 获取正确的实例

asp.net-mvc - model.isvalid mvc servicestack 流畅验证

c# - 不需要的文化特定 dll 复制到 bin 目录

c# - 使用 Parallel.ForEach() 时防止远程系统过载

java - 仅 Autowiring 构造函数的某些参数

validation - 如何验证温莎城堡的配置

javascript - 在创建不显示错误消息的部分 View 的集合上使用 FluentValidation