Lightinject 中的 FluentValidation

FluentValidation in Lightinject

我正在使用 fluentvalidation and lightinject

这是我插入博客文章的代码;

public OperationResultDto Add(BlogArticleDto blogArticleDto) { OperationResultDto 结果 = new OperationResultDto();

    ValidationResult validationResult = 
        _blogArticleModelValidator.Validate(blogArticleDto);

    if (!validationResult.IsValid)
    {
        result.IsOk = false;

        ValidationFailure firstValidationFailer = 
            validationResult.Errors.FirstOrDefault();

        if (firstValidationFailer != null)
        {
            result.Message = firstValidationFailer.ErrorMessage;
        }

        return result;
    }

    BlogArticle blogArticle = new BlogArticle {
        Title = blogArticleDto.Title,
        ShortBody = blogArticleDto.ShortBody,
        Body = blogArticleDto.Body,
        IsOnline = blogArticleDto.IsOnline,
        CategoryName = blogArticleDto.CategoryName,
        PublishedBy = blogArticleDto.PublishedBy,
        PublishDate = blogArticleDto.PublishDate,
        Tags = new List<string>(), //TODO parse, model's tags in one string.
        CreateDate = DateTime.Now,
        MainPhotoPath = blogArticleDto.MainPhotoPath,
    };

    _blogArticleRepository.Add(blogArticle);

    return result;
}

如您所见,"validation section" 很大,我不想在我的服务(业务)层中验证我的 dto 参数。我想在我的 ioc (lightinject) 中验证 "arguments"。

这是我的 ioc 代码以继续该操作;

public class ServiceInterceptor : IInterceptor
{
    public object Invoke(IInvocationInfo invocationInfo)
    {
        Log.Instance.Debug("Class: ServiceInterceptor -> Method: Invoke started.");

        string reflectedTypeFullname = String.Empty;
        string methodName = String.Empty;

        if (invocationInfo.Arguments.Any())
        {
            //TODO Validate method parameters here..

            foreach (object argument in invocationInfo.Arguments)
            {
            }
        }

        if (invocationInfo.Method.ReflectedType != null)
        {
            reflectedTypeFullname = invocationInfo.Method.ReflectedType.FullName;
            methodName = invocationInfo.Method.Name;
        }

        ... ...

现在,我可以将方法的所有参数提供给我的流利验证器。所以我知道我需要在这里定义 typeOf 参数,但在那之后我如何调用流畅验证的相关验证对象*来验证参数?

我是 LightInject 的作者,也许你可以看看这个例子是否适合你。

class Program
{
    static void Main(string[] args)
    {
        var container = new ServiceContainer();
        container.Register<AbstractValidator<Foo>, FooValidator>();    
        container.Register<IFooService, FooService>();
        container.Intercept(sr => sr.ServiceType.Name.EndsWith("Service"), factory => new ServiceInterceptior(factory));
        var service = container.GetInstance<IFooService>();
        service.Add(new Foo());
    }
}

public interface IFooService
{
    void Add(Foo foo);
}

public class FooService : IFooService
{
    public void Add(Foo foo)
    {
    }
}

public class Foo
{
}

public class FooValidator : AbstractValidator<Foo>
{
}

public class ServiceInterceptior : IInterceptor
{
    private readonly IServiceFactory factory;

    public ServiceInterceptior(IServiceFactory factory)
    {
        this.factory = factory;
    }

    public object Invoke(IInvocationInfo invocationInfo)
    {
        foreach (var argument in invocationInfo.Arguments)
        {
            Type argumentType = argument.GetType();
            Type validatorType = typeof (AbstractValidator<>).MakeGenericType(argumentType);
            var validator = factory.TryGetInstance(validatorType);
            if (validator != null)
            {
                var validateMethod = validatorType.GetMethod("Validate", new Type[] { argumentType });
                var result = (ValidationResult)validateMethod.Invoke(validator, new object[] { argument });
                if (!result.IsValid)
                {
                    //Throw an exception, log or any other action
                }
            }                
        }

        //if ok, proceed to the actual service.
        return invocationInfo.Proceed();
    }
}