What are the best practices with implementation of Dryioc, Fluentvalidation and Lazy?

Asked

Viewed 293 times

12

I’m building an architecture based on the use of Lazy, DryIoc e o FluentValidation.

I intend to do all validations with the object. When actually using the object I will instantiate it (Start). I don’t know if I’m sinning in any detail with the use of Lazy and the Dryioc, did not find example of how to implement them in the same solution.

I’d appreciate it if someone would open my eyes to some blind spot I missed, or tell me how to do it properly.

Entree.

    using DryIoc;
    using FluentValidation;
    using System;
    using System.Linq;
    using TesteDryIoC.Generic.Validacoes;

    namespace TesteDryIoC.Generic
    {
    class Program
    {
        static void Main(string[] args)
        {
            var container = ContainerRegister.getContainer();

            // buscar a validador especifico por propriedade
            var validadorPropriedade = ProvadersValidator<Cliente>.GetValidators(container, (validadores) =>
            {
                var validadorEncontrado = validadores.FirstOrDefault(x => x.CreateDescriptor().GetRulesForMember("Observacao").Any());
                return validadorEncontrado ?? validadores.First();
            });

            var validadorRule = ProvadersValidator<Cliente>.GetValidators(container, (validadores) =>
            {
                var validadorEncontrado = validadores.FirstOrDefault(x => x. CreateDescriptor().GetValidatorsForMember("ClienteValidatorRuleSet").Any());
                return validadorEncontrado ?? validadores.First();
            });


            Console.WriteLine("cliente1");
            Cliente cliente = new Cliente();
            cliente.Nome = "Marconcilio";
            cliente.SobreNome = "Souza";
            cliente.Observacao = "teste";
            cliente.Email = "[email protected]";
            cliente.Idade = 32;
            cliente.DtInclusao = DateTime.Now;
            cliente.Ativo = true;
            cliente.Senha = "";

            var resultad = validadorPropriedade.Validate(cliente);

            foreach (var item in resultad.Errors)
            {
                Console.WriteLine(item.ErrorMessage);
            }
            Console.ReadKey();
            }
        }
    }

Client class

  using FluentValidation.Results;
  using System;

  namespace TesteDryIoC.Generic {
   public class Cliente {
    public string Nome {
     get;
     set;
    }
    public string SobreNome {
     get;
     set;
    }
    public string Email {
     get;
     set;
    }
    public int Idade {
     get;
     set;
    }
    public string Observacao {
     get;
     set;
    }
    public DateTime DtInclusao {
     get;
     set;
    }
    public bool Ativo {
     get;
     set;
    }
    public string Senha {
     get;
     set;
    }
   }
  }

Container Register

using DryIoc;
using FluentValidation;
using System.Linq;
using System.Reflection;

namespace TesteDryIoC.Generic {
 public static class ContainerRegister {
  public static Container getContainer() {
   Container container = new Container();

   var implementingClasses =
    Assembly.GetExecutingAssembly()
    .GetTypes().Where(type =>
     type.ImplementsServiceType(typeof(IValidator))
    );

   foreach(var implementingClass in implementingClasses) {
    var interfaceValidator = implementingClass.GetImplementedInterfaces()[0];
    container.Register(interfaceValidator, implementingClass);
   }

   return container;
  }
 }
}

Provaders Validator

using DryIoc;
using FluentValidation;
using System;
using System.Collections.Generic;
using System.Linq;

namespace TesteDryIoC.Generic {
 public static class ProvadersValidator < T1 > where T1: class {
  public static IValidator GetValidators(Container container, Func < IEnumerable < IValidator < T1 >> , IValidator < T1 >> criterio = null) {
   var validador = container.Resolve < Lazy < IEnumerable < IValidator < T1 >>> > ();
   var validadores = validador.Value;
   // TODO: função para selecionar qual usar
   if (criterio != null)
    return criterio(validadores);

   return validadores.First();
  }
 }
}

Validation class

using FluentValidation;
using System;

namespace TesteDryIoC.Generic.Validacoes {
 public class ClienteValidator: AbstractValidator < Cliente > {
  public ClienteValidator() {
   RuleFor(x => x.Nome)
    // Garante que a propriedade especificada não seja nula                            
    .NotNull().WithMessage("{PropertyName} deve ser preenchido")
    //  Garante que a propriedade especificada não seja nula, uma string vazia ou espaço em branco (ou o valor padrão para tipos de valor, por exemplo, 0 para int
    .NotEmpty().WithMessage("{PropertyName} não pode estar em branco")
    // Especificar o tamanho minimo para o nome
    .MinimumLength(2).WithMessage("{PropertyName} não pode ter menos que 2 caracteres")
    // especificar o tamanho máximo para o nome
    .MaximumLength(200).WithMessage("{PropertyName} não pode ser maior que 200")
    // Garante que o valor da propriedade especificada não seja igual a um valor específico 
    .NotEqual("Carlos").WithMessage("{PropertyName} não pode igual a Carlos")
    //(ou não igual ao valor de outra propriedade)
    .NotEqual(c => c.SobreNome).WithMessage("{PropertyName} não pode igual ao sobrenome");

   RuleFor(x => x.Idade)
    .NotNull()
    .NotEmpty()
    // Garante que o valor da propriedade especificada seja maior do que um valor específico(ou maior que o valor de outra propriedade)
    .GreaterThan(18).WithMessage("{PropertyName} Minima é 18 anos!");

   // Garante que o comprimento de uma propriedade de string específica esteja dentro do intervalo especificado.
   RuleFor(x => x.Observacao)
    .Length(10, 250)
    .WithMessage("{PropertyName} tem que ter entre 10 e 250 caracteres");

   // Garante que o valor da propriedade especificada seja um formato de endereço de e-mail válido.
   RuleFor(x => x.Email)
    .EmailAddress().WithMessage("{ PropertyName} é inválido");

   //  Passa o valor da propriedade especificada para um delegate personalizado que pode executar a lógica de validação personalizada no valor
   RuleFor(x => x.DtInclusao).Must(ClienteValidatorDate).WithMessage("{ PropertyName} é inválido");

   //  Garante que o valor da propriedade especificada corresponda à expressão regular dada
   RuleFor(x => x.Senha)
    .Matches("").WithMessage("{ PropertyName} é inválido");

  }

  private bool ClienteValidatorDate(DateTime date) {
   if (date ==
    default (DateTime))
    return false;
   return true;
  }
  private bool ClienteValidatorDate(DateTime ? date) {
   if (date ==
    default (DateTime))
    return false;
   return true;
  }
 }
}
  • How could I turn my class ProvadersValidator for return a generic type instead of the IValidator return the type that is being filtered in the (container) case ClienteValidator?

1 answer

1


I think I understand your doubt, to do what you want it would be enough to let the following classes change:

Program:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("cliente1");
        var cliente = new Cliente {
            Nome = "Marconcilio",
            SobreNome = "Souza",
            Observacao = "teste",
            Email = "[email protected]",
            Idade = 32,
            DtInclusao = DateTime.Now,
            Ativo = true,
            Senha = ""
        };

        // Validando com qualquer validador, pega o primeiro disponível e retorna uma exception se não houver validador registrado.
        var validandoComQualquerValidador = ProvadersValidator<Cliente>.Validate(cliente);
        // Validando com validador localizado propropriedade.
        var validandoComValidadorLocalizadoPorPropriedade = ProvadersValidator<Cliente>.Validate(cliente, x => 
            x.CreateDescriptor().GetRulesForMember("Observacao").Any());
        // Validando com validador localizado por rule.
        var validandoComValidadorLocalizadoPorRule = ProvadersValidator<Cliente>.Validate(cliente, x =>
            x.CreateDescriptor().GetValidatorsForMember("ClienteValidatorRuleSet").Any());

        foreach (var item in validandoComQualquerValidador.Errors)
            Console.WriteLine(item.ErrorMessage);

        foreach (var item in validandoComValidadorLocalizadoPorPropriedade.Errors)
            Console.WriteLine(item.ErrorMessage);

        foreach (var item in validandoComValidadorLocalizadoPorRule.Errors)
            Console.WriteLine(item.ErrorMessage);

        Console.ReadKey();
    }
}

Provadersvalidator:

public static class ProvadersValidator
{
    public static IValidator GetValidator<T>(Func<IValidator, bool> clause = null)
    {
        var container = ContainerRegister.GetContainer();
        var validators = container.Resolve<Lazy<IEnumerable<IValidator<T>>>>().Value;

        if (validators == null || !validators.Any())
            throw new Exception(
                $"Não foram localizados validadores para a classe {typeof(T).FullName}"
            );

        if (clause == null) return validators.First();

        var filtered = validators.Where(clause);

        return filtered.Any() ? filtered.First() : validators.First();
    }

    public static ValidationResult Validate<T>(T target)
    {
        var validator = GetValidator<T>();
        var result = validator.Validate(target);
        return result;
    }

    public static ValidationResult Validate<T>(T target, Func<IValidator, bool> clause)
    {
        var validator = GetValidator<T>(clause);
        var result = validator.Validate(target);
        return result;
    }
}

PS: It was not necessary to intervene in the other classes...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.