RysePackage.Complex 1.0.1

dotnet add package RysePackage.Complex --version 1.0.1
                    
NuGet\Install-Package RysePackage.Complex -Version 1.0.1
                    
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="RysePackage.Complex" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RysePackage.Complex" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="RysePackage.Complex" />
                    
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 RysePackage.Complex --version 1.0.1
                    
#r "nuget: RysePackage.Complex, 1.0.1"
                    
#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 RysePackage.Complex@1.0.1
                    
#: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=RysePackage.Complex&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=RysePackage.Complex&version=1.0.1
                    
Install as a Cake Tool

Complex

Complex e uma biblioteca utilitaria para APIs .NET com foco em:

  • padronizacao de retorno com Result, ErrorState e ApiResponse
  • conversao de resultados de aplicacao para ActionResult
  • validacoes comuns de documentos e campos
  • hash de senha
  • leitura de usuario autenticado via claims
  • helpers auxiliares para dominio, avatar, paginacao e geolocalizacao

O pacote publicado e RysePackage.Complex e atualmente tem alvo em net10.0.

Instalacao

dotnet add package RysePackage.Complex

Namespaces mais usados:

using Complex.Application.Common.Errors;
using Complex.Application.Common.Extensions;
using Complex.Application.Common.Hashers;
using Complex.Application.Common.Models;
using Complex.Application.Common.Responses;
using Complex.Application.Common.Security;

Visao geral rapida

O fluxo principal da biblioteca e:

  1. a camada de aplicacao retorna Result ou Result<T>
  2. erros sao descritos por ErrorState
  3. a controller converte isso para HTTP com ToActionResult()
  4. o cliente recebe um payload padrao com ApiResponse<T>

Exemplo resumido:

public Result<UsuarioDto> ObterUsuario(Guid id)
{
    var usuario = _repositorio.Buscar(id);

    if (usuario is null)
        return Result<UsuarioDto>.Fail(ErrorState.NotFound("Usuario nao encontrado."));

    return Result<UsuarioDto>.Ok(usuario);
}

Em uma controller:

[HttpGet("{id:guid}")]
public ActionResult<ApiResponse<UsuarioDto>> Get(Guid id)
{
    var result = _service.ObterUsuario(id);
    return this.ToActionResult(result);
}

Result e ErrorState

Use Result.Ok() e Result<T>.Ok(valor) para sucesso.

return Result.Ok();
return Result<PedidoDto>.Ok(pedido);

Use Result.Fail(...) ou Result<T>.Fail(...) para falha.

return Result<PedidoDto>.Fail(
    ErrorState.Validation(
        "Dados invalidos.",
        new Dictionary<string, object?>
        {
            ["itens"] = new[] { "Ao menos um item e obrigatorio." }
        }));

Factories disponiveis em ErrorState:

  • Validation(message, meta)
  • NotFound(message, meta)
  • Conflict(message, meta)
  • Unexpected(message)

Campos importantes:

  • Code: codigo padrao do erro
  • Message: mensagem legivel
  • Meta: detalhes adicionais, como erros de validacao por campo

Integracao com ASP.NET Core

ResultToActionResultExtensions converte Result para respostas HTTP padronizadas.

Mapeamento atual de codigos:

  • validation400 Bad Request
  • not_found404 Not Found
  • conflict409 Conflict
  • forbidden403 Forbidden
  • unauthorized401 Unauthorized
  • qualquer outro → 500 Internal Server Error

Exemplo com mapeamento de DTO na saida:

[HttpGet("{id:guid}")]
public ActionResult<ApiResponse<UsuarioResponse>> Get(Guid id)
{
    var result = _service.ObterUsuario(id);

    return this.ToActionResult(result, usuario => new UsuarioResponse
    {
        Id = usuario.Id,
        Nome = usuario.Nome
    });
}

Exemplo para endpoints que devolvem 201 Created, 202 Accepted ou outro status de sucesso:

[HttpPost]
public IActionResult Post(CriarUsuarioRequest request)
{
    var result = _service.Criar(request);
    return this.ToIActionResult(HttpStatusCode.Created, result);
}

Formato esperado da resposta de sucesso:

{
  "data": {
    "id": "..."
  },
  "error": null,
  "message": "OK",
  "success": true
}

Formato esperado da resposta de erro:

{
  "data": null,
  "error": {
    "code": "validation",
    "message": "Dados invalidos.",
    "meta": {
      "email": [
        "Email invalido."
      ]
    },
    "traceId": "..."
  },
  "message": "Error",
  "success": false
}

Excecoes de dominio

A biblioteca fornece excecoes que implementam ToError() para conversao em ErrorState:

  • BusinessException
  • DomainException
  • ConflictException
  • NotFoundException
  • ComponentException

Exemplo:

try
{
    // regra de negocio
}
catch (AppException ex)
{
    return Result.Fail(ex.ToError());
}

IntegrationException tambem expoe ToError(), mas e uma base abstrata separada de AppException.

Validacoes comuns

Extensoes disponiveis para strings:

  • IsValidCpf()
  • IsValidCnpj()
  • NormalizeCpf()
  • NormalizeCnpj()
  • OnlyDigits()
  • IsValidEmail()
  • IsValidPhone()
  • IsValidCep()
  • IsValidUrlOuUser()
  • IsValidBasicPassword()

Exemplo:

if (!request.Cpf.IsValidCpf())
    return Result.Fail(ErrorState.Validation("CPF invalido."));

if (!request.Email.IsValidEmail())
    return Result.Fail(ErrorState.Validation("Email invalido."));

Para montar Meta de erro de validacao:

var erros = new List<string> { "CPF invalido.", "CPF obrigatorio." };

return Result.Fail(
    ErrorState.Validation(
        "Falha de validacao.",
        erros.ToDictionaryObject("cpf")));

Se voce estiver lidando com IDictionary, tambem pode converter para IReadOnlyDictionary<string, object?> com:

  • ToReadOnlyDictionary()
  • AsReadOnly()

Senhas

PasswordHasher usa PBKDF2 com SHA-256, salt aleatorio e 100_000 iteracoes.

var (hashBase64, saltBase64) = PasswordHasher.Hash(request.Password);

var senhaConfere = PasswordHasher.Verify(
    request.Password,
    hashBase64,
    saltBase64);

Observacoes:

  • Hash() lanca DomainException se a senha for nula, vazia ou tiver menos de 8 caracteres
  • armazene hashBase64 e saltBase64
  • Verify() compara em tempo constante

Usuario autenticado e claims

Para expor o usuario atual via DI:

builder.Services.AddHttpContextAccessor();
builder.Services.AddScoped<ICurrentUser, HttpContextCurrentUser>();

Depois disso:

public sealed class UsuarioAppService
{
    private readonly ICurrentUser _currentUser;

    public UsuarioAppService(ICurrentUser currentUser)
    {
        _currentUser = currentUser;
    }

    public Guid ObterUsuarioLogado() => _currentUser.UsuarioId;
}

Claims esperadas por HttpContextCurrentUser e ClaimsPrincipalExtensions:

  • usuario_id
  • empresa_id
  • pessoa_id
  • ClaimTypes.Email

Uso direto no ClaimsPrincipal:

var usuarioId = User.GetUsuarioId();
var email = User.GetEmail();

Se as claims nao existirem ou forem invalidas, a biblioteca lanca UnauthorizedAccessException.

Validacao de dominio com Domains

Domains e uma base para entidades ou objetos que acumulam erros de validacao e retornam ReturnModel<List<string>>.

Exemplo:

public sealed class UsuarioDomain : Domains
{
    private readonly string _nome;

    public UsuarioDomain(string nome)
    {
        _nome = nome;
    }

    public override ReturnModel<List<string>> Validate()
    {
        ClearValidation();

        if (string.IsNullOrWhiteSpace(_nome))
            AddError("Nome e obrigatorio.");

        return CheckValidade();
    }
}

Observacao importante: o metodo publico da base se chama CheckValidade().

Outros recursos

PagedResult<T>

Wrapper simples para retorno paginado:

var page = new PagedResult<UsuarioDto>(usuarios, total, paginaAtual, tamanhoPagina);

Builder<T>

Base para implementar builders fluentes ou factories orientadas a objeto:

public sealed class UsuarioBuilder : Builder<Usuario>
{
    public UsuarioBuilder ComNome(string nome)
    {
        Instance.Nome = nome;
        return this;
    }
}

AvatarHelper

Converte avatar em data: URI ou le arquivos enviados via IFormFile.

var (base64Bytes, mimeType) = await AvatarHelper.FromFormFileAsync(file);
var base64 = Encoding.UTF8.GetString(base64Bytes);
var dataUri = AvatarHelper.ToDataUri(base64, mimeType);

Tambem ha ReadRawAsync() para obter os bytes originais do arquivo.

GeoMath

Calcula o bearing entre dois pontos geograficos:

var bearing = GeoMath.BearingDegrees(-23.5505m, -46.6333m, -22.9068m, -43.1729m);

Enums de email

A biblioteca inclui os enums:

  • EmailType
  • EmailSenderOrigin

Eles sao uteis para padronizar contratos entre servicos de notificacao e templates.

Recomendacao de uso

Para novos endpoints, o caminho mais consistente dentro da biblioteca e:

  1. retornar Result ou Result<T> na aplicacao
  2. representar falhas com ErrorState
  3. converter na controller com ToActionResult() ou ToIActionResult()
  4. usar as extensoes de validacao para evitar codigo repetido
  5. usar ICurrentUser quando a regra depender do usuario autenticado

Limitacoes observadas na analise

  • a biblioteca nao traz middleware global para capturar excecoes automaticamente
  • a integracao HTTP atual foi feita para ControllerBase, nao para Minimal APIs
  • nao ha testes automatizados no projeto neste estado
  • coexistem dois modelos de retorno: Result/ApiResponse e ReturnModel; para novos fluxos, Result tende a ser o mais direto para APIs
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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. 
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
1.0.1 122 4/13/2026
1.0.0 134 3/26/2026