CentimxArchitecture 0.5.0

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

CentimxArchitecture

Arquitectura reutilizable para servicios ASP.NET Core sobre .NET 10, SQL Server y Dapper. La solución separa las reglas transversales en paquetes NuGet y deja en cada sistema de negocio únicamente dominio, casos de uso, contratos y adaptadores propios.

La entrada recomendada es el paquete CentimxArchitecture. Esta fachada permite composición modular o registra web, seguridad JWT, acceso a SQL Server, transacciones, observabilidad y caché híbrida/Redis con una sola llamada. Los namespaces y ensamblados conservan el prefijo técnico NFC.Architecture.

Estructura

NFC.Architecture.sln
├─ src/                                      paquetes NuGet reutilizables
│  ├─ NFC.Architecture.Abstractions          resultados, errores y contratos neutrales
│  ├─ NFC.Architecture.Operations             handlers y pipeline ordenado de behaviors
│  ├─ NFC.Architecture.Data.Abstractions     requests USP y repositorio genérico tipado
│  ├─ NFC.Architecture.Data.SqlServer.Dapper repositorio USP, Dapper, transacciones y health check
│  ├─ NFC.Architecture.Data.Caching          caché declarativo de Queries e invalidación de Commands
│  ├─ NFC.Architecture.Migrations.SqlServer  migraciones versionadas y controladas
│  ├─ NFC.Architecture.Security.JwtBearer    autenticación, autorización y usuario actual
│  ├─ NFC.Architecture.Observability         trazas y métricas OpenTelemetry
│  ├─ NFC.Architecture.Caching.Abstractions  contrato de caché neutral
│  ├─ NFC.Architecture.Caching.Hybrid        caché L1/L2, tags y protección de stampede
│  ├─ NFC.Architecture.Caching.Redis         proveedor distribuido Redis opcional
│  ├─ NFC.Architecture.Validation.DataAnnotations validación automática de Application
│  ├─ NFC.Architecture.AspNetCore             Problem Details, CORS, límites, OpenAPI y salud
│  ├─ NFC.Architecture.AspNetCore.SqlServer  fachada de instalación
│  └─ NFC.Architecture.Testing               dobles neutrales para proyectos consumidores
├─ samples/                                  solución de negocio de referencia
│  ├─ NFC.Architecture.Sample.Application
│  ├─ NFC.Architecture.Sample.Infrastructure
│  └─ NFC.Architecture.Sample.Api
└─ tests/                                    pruebas unitarias, de arquitectura e integración

La dirección de dependencias esperada en una solución consumidora es:

Api ────────────────┐
 │                  │ composición y endpoints
 ├─> Application ──> Domain
 ├─> Contracts
 └─> Infrastructure ──> adaptadores especiales y servicios externos

Domain: proyecto opcional cuando existen agregados, invariantes o comportamiento de dominio real
Application: vertical slices con requests, responses, handlers y requests USP; no conoce Dapper ni ASP.NET Core
Infrastructure: implementa sólo adaptadores especiales; el repositorio USP genérico viene del paquete
Api: es la raíz de composición; no contiene lógica de negocio

Uso desde una solución de negocio

Instale el paquete fachada desde el feed NuGet de la organización:

dotnet add <Proyecto.Api> package CentimxArchitecture --version 0.5.0

El Program.cs del proyecto API queda reducido a la composición:

using NFC.Architecture.AspNetCore.SqlServer;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddNfcArchitectureBuilder(builder.Configuration, builder.Environment)
    .AddWebApi()
    .AddOperations(typeof(ApplicationMarker).Assembly)
    .AddJwtBearer()
    .AddSqlServer()
    .AddRedisHybridCache()
    .AddObservability();
builder.Services.AddApplication();
builder.Services.AddInfrastructure();

WebApplication app = builder.Build();

app.UseNfcArchitecture();
app.MapControllers();
app.MapNfcArchitectureEndpoints();

app.Run();

Para la instalación completa con los valores predeterminados continúa disponible builder.Services.AddNfcArchitecture(builder.Configuration, builder.Environment).

Cada operación declara explícitamente si es Command o Query, el nombre de su USP y la forma tipada del resultado. Los servicios sólo inyectan ICommandExecutor para escrituras e IQueryExecutor para lecturas; el repositorio, Dapper y los contratos de ejecución de stored procedures quedan detrás de esos ejecutores. Las reglas de negocio pueden componerse con ToResult, Ensure, Map y Bind.

La versión 0.5 mantiene eliminada la ejecución pública de SQL crudo: no expone IDataExecutor, DbCommandSpec ni CommandType.Text. Todo acceso normal a datos pasa por una clase de stored procedure y por un nombre validado antes de abrir la conexión. También agrega un pipeline neutral de handlers y behaviors para políticas transversales sin incorporar reglas de negocio al paquete.

Las operaciones atómicas se delimitan con IUnitOfWork. ExecuteAsync confirma si no hay excepciones; ExecuteResultAsync confirma exclusivamente un Result.Success y revierte automáticamente un Result.Failure. UnitOfWorkOptions permite escoger el aislamiento por caso de uso. Los casos de uso se registran con AddValidatedScoped<TUseCase, TImplementation>() para ejecutar automáticamente sus DataAnnotations.

Consulte el ejemplo ejecutable en samples/NFC.Architecture.Sample.Api, el pipeline de operaciones, la comparación con DigitAI, la guía de adopción, el repositorio genérico de procedimientos, el diseño de casos de uso, la caché, las migraciones, las utilidades de testing y el diseño de validación.

Configuración

Toda la configuración está bajo NfcArchitecture; las cadenas permanecen en ConnectionStrings. El arranque valida combinaciones inseguras o incompletas antes de atender tráfico.

{
  "ConnectionStrings": {
    "DefaultConnection": "<secret>",
    "Redis": "<secret>"
  },
  "NfcArchitecture": {
    "Database": {
      "ConnectionStringName": "DefaultConnection",
      "CommandTimeoutSeconds": 30,
      "EnableRetry": true,
      "MaxRetryAttempts": 3,
      "RetryDelayMilliseconds": 200,
      "TransactionIsolationLevel": "ReadCommitted"
    },
    "Security": {
      "Enabled": true,
      "Mode": "ExternalAuthority",
      "Authority": "https://identity.example.com",
      "Issuer": "https://identity.example.com",
      "Audience": "business-api",
      "RequireHttpsMetadata": true,
      "RequireAuthenticatedUserByDefault": true,
      "ClockSkewSeconds": 30
    },
    "WebApi": {
      "Documentation": "DevelopmentOnly",
      "AllowedOrigins": [ "https://app.example.com" ],
      "AllowAnyOrigin": false,
      "AllowCredentials": false,
      "ExposedHeaders": [ "Location", "Retry-After" ],
      "PreflightMaxAgeSeconds": 600,
      "RateLimiting": {
        "Enabled": true,
        "PermitLimit": 100,
        "WindowSeconds": 60,
        "QueueLimit": 0,
        "PartitionStrategy": "UserOrIp"
      }
    },
    "Observability": {
      "Enabled": true,
      "OtlpEndpoint": "https://otel-collector.example.com",
      "TraceSampleRatio": 0.1
    },
    "Caching": {
      "Enabled": false,
      "ConnectionStringName": "Redis",
      "InstanceName": "business:",
      "KeyPrefix": "business:",
      "DefaultTtlSeconds": 300,
      "LocalTtlSeconds": 60
    },
    "Migrations": {
      "CommandTimeoutSeconds": 60,
      "MigrateOnStartup": false,
      "AllowRollback": false,
      "LockResource": "CentimxArchitecture:SqlServer:Migrations",
      "LockTimeoutSeconds": 60,
      "ValidateChecksums": true,
      "BaselineMissingChecksums": true
    }
  }
}

No almacene contraseñas, llaves simétricas ni cadenas productivas en archivos versionados. Use variables de entorno, secretos de desarrollo o el almacén de secretos de la plataforma.

Conexiones y transacciones

  • Cada operación autónoma abre una conexión lógica, la usa y la desecha de forma asíncrona. El pool de Microsoft.Data.SqlClient reutiliza las conexiones físicas; no se comparte un SqlConnection singleton.
  • IUnitOfWork abre una conexión y una transacción explícitas y las reutiliza entre los repositorios llamados dentro de su delegado. Confirma al terminar, revierte ante cualquier excepción y, con ExecuteResultAsync, también ante un resultado fallido.
  • Las transacciones anidadas se rechazan. Una operación debe tener un único propietario transaccional.
  • ExecuteBatchAsync ejecuta una secuencia tipada dentro de la conexión/transacción ambiente. DbParameters.AddTable e IDbParameterProvider habilitan TVP sin exponer Dapper ni SqlParameter.
  • Las excepciones SQL se traducen a códigos estables para unicidad, referencias, valores inválidos, timeout, deadlock, indisponibilidad y rechazos del comando.
  • Los reintentos sólo se ejecutan para comandos marcados como idempotentes y fuera de una transacción. Nunca se reintenta automáticamente una escritura ni una transacción completa.
  • El CancellationToken de la solicitud llega a apertura de conexión, comandos, lecturas, confirmación y esperas de reintento.

La guía completa de decisiones está en conexiones y transacciones.

Seguridad y operación

  • JWT valida emisor, audiencia, firma, vigencia y expiración. El modo recomendado en producción es ExternalAuthority con metadatos HTTPS.
  • La política de respaldo exige usuario autenticado por defecto cuando la seguridad está habilitada. Los endpoints públicos deben declararse explícitamente anónimos.
  • Las excepciones se convierten en RFC 7807 Problem Details sin filtrar detalles internos en producción.
  • MVC valida automáticamente DataAnnotations, incluidos parámetros de ruta y cuerpos, mediante un filtro global que no depende de recordar ModelState.IsValid. Application repite la protección en el proxy del servicio para consumidores no HTTP.
  • Se incluyen identificador de correlación, CORS restrictivo, rate limiting particionado por usuario/IP con Retry-After, HSTS/HTTPS, /health/live, /health/ready, OpenAPI y Scalar controlados por ambiente.
  • OpenTelemetry publica instrumentación ASP.NET Core/HTTP y telemetría de operaciones SQL sin registrar texto SQL ni parámetros.

Compilar, probar y empaquetar

dotnet restore NFC.Architecture.sln
dotnet test NFC.Architecture.sln -c Release
./build/pack.ps1

Para publicar, configure la API key fuera del repositorio y ejecute:

$env:CENTIMX_NUGET_API_KEY = '<api-key>'
./build/publish.ps1

El script publica primero los módulos y al final la fachada CentimxArchitecture; usa --skip-duplicate para permitir reintentos seguros de una misma versión.

El número de versión común se controla con VersionPrefix en Directory.Build.props. Los proyectos de ejemplo y pruebas tienen IsPackable=false; sólo se generan paquetes para los módulos de src. El empaquetado ejecuta Package Validation para detectar incompatibilidades estructurales.

Alcance

El paquete ofrece infraestructura transversal y reglas seguras por defecto. No intenta definir entidades, DTO, nombres de procedimientos, reglas de negocio ni estructura interna de cada caso de uso. Esas decisiones permanecen en la solución consumidora.

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
0.5.0 105 8/29/2026
0.3.2 109 8/28/2026
0.1.0 105 8/19/2026