MarceloCastelo.IO.OutputEnvelop.FluentValidation 2.1.0

The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package MarceloCastelo.IO.OutputEnvelop.FluentValidation --version 2.1.0
                    
NuGet\Install-Package MarceloCastelo.IO.OutputEnvelop.FluentValidation -Version 2.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MarceloCastelo.IO.OutputEnvelop.FluentValidation" Version="2.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MarceloCastelo.IO.OutputEnvelop.FluentValidation" Version="2.1.0" />
                    
Directory.Packages.props
<PackageReference Include="MarceloCastelo.IO.OutputEnvelop.FluentValidation" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MarceloCastelo.IO.OutputEnvelop.FluentValidation --version 2.1.0
                    
#r "nuget: MarceloCastelo.IO.OutputEnvelop.FluentValidation, 2.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MarceloCastelo.IO.OutputEnvelop.FluentValidation@2.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MarceloCastelo.IO.OutputEnvelop.FluentValidation&version=2.1.0
                    
Install as a Cake Addin
#tool nuget:?package=MarceloCastelo.IO.OutputEnvelop.FluentValidation&version=2.1.0
                    
Install as a Cake Tool

MCIO.OutputEnvelop.FluentValidation

Uma extensão do pacote MarceloCastelo.IO.OutputEnvelop que integra com o pacote FluentValidation.

📦 Pacotes

Nome Versão Link Repository
MarceloCastelo.IO.OutputEnvelop Nuget Nuget.org Link
MarceloCastelo.IO.OutputEnvelop.FluentValidation Nuget Nuget.org Esse aqui 😃

🏷️ Labels

Categoria Descrição Labels (todos os ícones são clicáveis e levam as ferramentas externas)
Licença MIT MIT License
Segurança Vulnerabilidades CodeQL Vulnerabilities Security Rating
Qualidade Visão geral Quality Gate Status
Qualidade Cobertura de testes Coverage
Qualidade Teste de mutação Mutation Test
Qualidade Manutenabilidade Maintainability Rating
Qualidade Confiabilidade Reliability Rating
Qualidade Bugs Bugs
Qualidade Dívidas técnicas Technical Debt
Qualidade Linhas duplicadas (%) Duplicated Lines (%)
Qualidade Melhorias de código Code Smells
Pipeline Compilação e testes Build and Test
Pipeline Publicação Publish

📄 Introdução

O pacote FluentValidation é amplamente utilizado em projetos .NET devido à sua robustez e flexibilidade, especialmente em validações de domínio. O pacote MarceloCastelo.IO.OutputEnvelop pode ser utilizado no lugar do FluentValidation. No entanto, é importante que eles possam funcionar lado a lado para proporcionar maior flexibilidade no projeto. Este pacote realiza a integração necessária para que possam coexistir harmoniosamente.

📖 Conteúdo

📦 Dependências

voltar ao topo

📚 Utilização básica

voltar ao topo

  • Sem objeto de retorno
using MCIO.OutputEnvelop;

var validationResult = someValidator.Validate(input);
var outputEnvelop = validationResult.ToOutputEnvelop();
  • Com objeto de retorno
using MCIO.OutputEnvelop;

var customer = new Customer();
var validationResult = someValidator.Validate(input);
var outputEnvelop = validationResult.ToOutputEnvelop(customer);

📚 Exemplo completo

voltar ao topo

public class Customer
{
    // Fields
    private static RegisterNewCustomerInputValidator _registerNewCustomerInputValidator = new();

    // Properties
    public int Id { get; }
    public string Name { get; }
    public DateOnly BirthDate { get; }

    // Constructors
    private Customer(int id, string name, DateOnly birthDate)
    {
        Id = id;
        Name = name;
        BirthDate = birthDate;
    }

    // Public Methods
    // Validation result is a out variable for test reasons
    public static OutputEnvelop<Customer> RegisterNew(RegisterNewCustomerInput input, out ValidationResult validationResult)
    {
        // Validation
        validationResult = _registerNewCustomerInputValidator.Validate(input);
        if (!validationResult.IsValid)
            return validationResult.ToOutputEnvelop<Customer>(output: null!);

        // Process and return
        return validationResult.ToOutputEnvelop(
            output: validationResult.IsValid ? new Customer(id: input.Id, name: input.Name, birthDate: input.BirthDate) : null!
        );
    }

    // Inputs
    public record RegisterNewCustomerInput(int Id, string Name, DateOnly BirthDate);

    public class RegisterNewCustomerInputValidator
        : AbstractValidator<RegisterNewCustomerInput>
    {
        // Constants
        public const string CUSTOMER_ID_IS_REQUIRED_MESSAGE_CODE = "CUSTOMER_ID_IS_REQUIRED";
        public const string CUSTOMER_ID_IS_REQUIRED_MESSAGE_DESCRIPTION = "Id is required";
        public const Severity CUSTOMER_ID_IS_REQUIRED_MESSAGE_SEVERITY = Severity.Error;

        public const string CUSTOMER_NAME_IS_REQUIRED_MESSAGE_CODE = "CUSTOMER_NAME_IS_REQUIRED";
        public const string CUSTOMER_NAME_IS_REQUIRED_MESSAGE_DESCRIPTION = "Name is required";
        public const Severity CUSTOMER_NAME_IS_REQUIRED_MESSAGE_SEVERITY = Severity.Error;

        public const string CUSTOMER_NAME_SHOULD_HAVE_LAST_NAME_MESSAGE_CODE = "CUSTOMER_NAME_SHOULD_HAVE_LAST_NAME";
        public const string CUSTOMER_NAME_SHOULD_HAVE_LAST_NAME_MESSAGE_DESCRIPTION = "Name should have last name";
        public const Severity CUSTOMER_NAME_SHOULD_HAVE_LAST_NAME_MESSAGE_SEVERITY = Severity.Warning;
        
        public const string CUSTOMER_BIRTHDATE_IS_REQUIRED_MESSAGE_CODE = "CUSTOMER_BIRTHDATE_IS_REQUIRED";
        public const string CUSTOMER_BIRTHDATE_IS_REQUIRED_MESSAGE_DESCRIPTION = "BirthDate is required";
        public const Severity CUSTOMER_BIRTHDATE_IS_REQUIRED_MESSAGE_SEVERITY = Severity.Error;

        public const string CUSTOMER_BIRTHDATE_SHOULD_HAVE_MAX_LENGTH_MESSAGE_CODE = "CUSTOMER_BIRTHDATE_SHOULD_HAVE_MAX_LENGTH";
        public const string CUSTOMER_BIRTHDATE_SHOULD_HAVE_MAX_LENGTH_MESSAGE_DESCRIPTION = "BirthDate is required";
        public const Severity CUSTOMER_BIRTHDATE_SHOULD_HAVE_MAX_LENGTH_MESSAGE_SEVERITY = Severity.Error;

        public const string CUSTOMER_BIRTHDATE_DAY_MESSAGE_CODE = "CUSTOMER_BIRTHDATE_DAY";
        public const string CUSTOMER_BIRTHDATE_DAY_MESSAGE_DESCRIPTION = "Today is the customer birthday";
        public const Severity CUSTOMER_BIRTHDATE_DAY_MESSAGE_SEVERITY = Severity.Info;

        // Public Methods
        public RegisterNewCustomerInputValidator()
        {
            RuleFor(p => p.Id)
                .GreaterThan(0)
                .WithErrorCode(CUSTOMER_ID_IS_REQUIRED_MESSAGE_CODE)
                .WithMessage(CUSTOMER_ID_IS_REQUIRED_MESSAGE_DESCRIPTION)
                .WithSeverity(CUSTOMER_ID_IS_REQUIRED_MESSAGE_SEVERITY);

            RuleFor(p => p.Name)
                .NotEmpty()
                .WithErrorCode(CUSTOMER_NAME_IS_REQUIRED_MESSAGE_CODE)
                .WithMessage(CUSTOMER_NAME_IS_REQUIRED_MESSAGE_DESCRIPTION)
                .WithSeverity(CUSTOMER_NAME_IS_REQUIRED_MESSAGE_SEVERITY);
            
            RuleFor(p => p.Name)
                .MaximumLength(150)
                .WithErrorCode("CUSTOMER_NAME_SHOULD_HAVE_MAX_LENGTH")
                .WithMessage("Name should less than or equais 150 characters")
                .WithSeverity(Severity.Error);

            RuleFor(p => p.Name)
                .Must(name => name.Contains(" "))
                .WithErrorCode(CUSTOMER_NAME_SHOULD_HAVE_LAST_NAME_MESSAGE_CODE)
                .WithMessage(CUSTOMER_NAME_SHOULD_HAVE_LAST_NAME_MESSAGE_DESCRIPTION)
                .WithSeverity(CUSTOMER_NAME_SHOULD_HAVE_LAST_NAME_MESSAGE_SEVERITY);

            RuleFor(p => p.BirthDate)
                .NotEmpty()
                .WithErrorCode(CUSTOMER_BIRTHDATE_IS_REQUIRED_MESSAGE_CODE)
                .WithMessage(CUSTOMER_BIRTHDATE_IS_REQUIRED_MESSAGE_DESCRIPTION)
                .WithSeverity(CUSTOMER_BIRTHDATE_IS_REQUIRED_MESSAGE_SEVERITY);

            RuleFor(p => p.BirthDate)
                .LessThanOrEqualTo(DateOnly.FromDateTime(DateTime.Now))
                .WithErrorCode(CUSTOMER_BIRTHDATE_SHOULD_HAVE_MAX_LENGTH_MESSAGE_CODE)
                .WithMessage(CUSTOMER_BIRTHDATE_SHOULD_HAVE_MAX_LENGTH_MESSAGE_DESCRIPTION)
                .WithSeverity(CUSTOMER_BIRTHDATE_SHOULD_HAVE_MAX_LENGTH_MESSAGE_SEVERITY);

            RuleFor(p => p.BirthDate)
                .Must(q => q != DateOnly.FromDateTime(DateTime.Now))
                .WithErrorCode(CUSTOMER_BIRTHDATE_DAY_MESSAGE_CODE)
                .WithMessage(CUSTOMER_BIRTHDATE_DAY_MESSAGE_DESCRIPTION)
                .WithSeverity(CUSTOMER_BIRTHDATE_DAY_MESSAGE_SEVERITY);
        }
    }
}

🚀 Executando localmente

voltar ao topo

Por se tratar de um pacote nuget, não existe uma execução. Porém, existe o script build-local-script que pode ser executado via PowerShell que realizará as seguintes ações:

  1. Instalará a CLI do ReportGenerator localmente para visualização do relatório de cobertura no formato opencover.
  2. Instalará a CLI do Stryker localmente para execução e visualização do relatório do teste de mutação.
  3. Restore do projeto.
  4. Build do projeto em modo release.
  5. Execução dos testes de unidade.
  6. Execução do teste de mutação.
  7. Abertura do relatório de cobertura no navegador web padrão.
  8. Abertura do relatório de teste mutante no navegador web padrão.

A partir do diretóio raiz do repositório, no PowerShell, execute o comando .\build-local-script.ps1.

Caso queira limpar todos os arquivos gerados, a partir do diretóio raiz do repositório, no PowerShell, execute o comando .\clear-local-script.ps1.

🚀 Benchmark

voltar ao topo

O benchmark abaixo (arquivo ExtensionMethodsBenchmark.cs) compara a utilização do objeto ValidationResult como retorno do método e gerando um OutputEnvelop a partir do ValidationResult gerado.

// * Summary *

BenchmarkDotNet v0.13.11, Windows 11 (10.0.22631.2861/23H2/2023Update/SunValley3)
AMD Ryzen 5 5600X, 1 CPU, 12 logical and 6 physical cores
.NET SDK 8.0.100
  [Host]     : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
  Job-BHOBUW : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2

LaunchCount=1  RunStrategy=Throughput
Method Mean Error StdDev Ratio RatioSD TotalCycles/Op CacheMisses/Op BranchInstructions/Op TotalIssues/Op BranchMispredictions/Op Timer/Op Gen0 Allocated Alloc Ratio
'ValidationResult From Valid Input' 2.126 us 0.0149 us 0.0140 us 1.00 0.00 4,955 10 1,754 7,701 7 21 0.0381 664 B 1.00
'OutputEnvelop From Valid Input' 2.142 us 0.0094 us 0.0088 us 1.01 0.01 4,969 11 1,775 7,748 7 22 0.0381 664 B 1.00
'ValidationResult From Invalid Input' 3.951 us 0.0223 us 0.0198 us 1.86 0.02 9,076 29 3,289 14,827 16 40 0.1297 2224 B 3.35
'OutputEnvelop From Invalid Input' 4.048 us 0.0152 us 0.0127 us 1.90 0.01 9,332 30 3,410 15,154 17 41 0.1373 2320 B 3.49
// * Hints *
Outliers
  ExtensionMethodsBenchmark.'OutputEnvelop From Valid Input': LaunchCount=1, RunStrategy=Throughput      -> 1 outlier  was  detected (2.12 us)
  ExtensionMethodsBenchmark.'ValidationResult From Invalid Input': LaunchCount=1, RunStrategy=Throughput -> 1 outlier  was  removed (4.01 us)
  ExtensionMethodsBenchmark.'OutputEnvelop From Invalid Input': LaunchCount=1, RunStrategy=Throughput    -> 2 outliers were removed (4.16 us, 4.19 us)

🧑‍🤝‍🧑 Contribuindo

voltar ao topo

Você está mais que convidado para constribuir. Caso tenha interesse e queira participar do projeto, não deixe de ver nosso manual de contribuição.

🧑‍🤝‍🧑 Autores

voltar ao topo

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated