TechsBCN.Platform.Infrastructure 0.0.36

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

TechsBCN.Platform.Infrastructure

TechsBCN.Platform.Infrastructure Es la capa de infraestructura de Platform. Su objetivo es conectar la aplicación con los sistemas externos para que la capa Application solo trabaje con interfaces, sin conocer los detalles técnicos de cada integración. Esta capa no debe contener lógica de negocio, reglas de dominio ni decisiones de flujo de aplicación.

Depende de TechsBCN.Platform.Application y TechsBCN.Platform.Domain.

Estructura

Infrastructure/
├── Repositories/
│   ├── BaseRepository.cs
│   ├── UserRepository.cs
│   ├── TokenRepository.cs
│   ├── TaskRepository.cs
│   ├── RabbitMqMessagingRepository.cs
│   ├── MicrosoftGraphEmailRepository.cs
│   ├── SmtpEmailRepository.cs
│   └── AzureBlobStorageRepository.cs
├── Helpers/
│   ├── RestHelper.cs
│   └── HttpHeadersExtensions.cs
├── Setup/
│   ├── TaskSetup.cs
│   ├── EmailSetup.cs
│   └── SmtpEmailSetup.cs
└── Exceptions/
    ├── RabbitMqException.cs
    └── BlobStorageException.cs

Repositorios (Repositories/)

BaseRepository<TEntity>

Su objetivo es proporcionar las operaciones CRUD genéricas que todos los repositorios del proyecto pueden reutilizar sin reimplementarlas. Los repositorios del proyecto heredan de BaseRepository<TEntity> e implementan la interfaz propia definida en Application.

Los repositorios de Platform usan Lazy<DbContext> para resolver el contexto. Para que funcionen correctamente, el proyecto debe registrar también el DbContext base apuntando al contexto propio:

Los repositorios sin lógica adicional heredan con el cuerpo vacío. Los que necesitan cargar relaciones sobrescriben GetBaseEntityQuery con Include(...). Los que tienen listados propios aplican filtros, ordenación y paginación de forma separada mediante ApplyPagination(query, limit, offset).

services.AddDbContext<MyContext>(opt => opt.UseSqlServer(connectionString));
services.AddScoped<DbContext>(sp => sp.GetRequiredService<MyContext>());

TokenRepository

Su objetivo es persistir y consultar los tokens de autenticación. Está implementado directamente en Platform — el proyecto no define su propio ITokenRepository ni TokenRepository, los registra directamente:

public class TokenRepository<TTokenType>(Lazy<DbContext> context) : BaseRepository<Token<TTokenType>>(context), ITokenRepository<TTokenType> { }
services.AddScoped<ITokenRepository<MyTokenType>, TechsBCN.Platform.Infrastructure.Repositories.TokenRepository<MyTokenType>>();

Para que funcione, el DbContext base debe estar registrado tal como se indica en BaseRepository.

UserRepository<TUser>

Su objetivo es proporcionar acceso a los usuarios sin que cada proyecto reimplemente las operaciones base. El proyecto solo define su propio UserRepository porque necesita un thin wrapper que adapte el Lazy<DbContext> al contexto propio — Platform no puede resolverlo directamente:

public class UserRepository<TUser>(Lazy<DbContext> context) : BaseRepository<TUser>(context), IUserRepository<TUser> where TUser : User { }
public class UserRepository(Lazy<MyContext> context)
    : TechsBCN.Platform.Infrastructure.Repositories.UserRepository<User>(new Lazy<DbContext>(() => context.Value)), IUserRepository { }

TaskRepository

Su objetivo es persistir y consultar el estado de las tareas en background. Se registra con AddScoped en el ServicesSetup del proyecto:

services.AddScoped<ITaskRepository<MyTaskType>, TechsBCN.Platform.Infrastructure.Repositories.TaskRepository<MyTaskType>>();

Si el proyecto también necesita exponer el estado de las tareas vía API, ITaskService se registra de forma separada:

services.AddScoped<ITaskRepository<MyTaskType>, TechsBCN.Platform.Infrastructure.Repositories.TaskRepository<MyTaskType>>();
services.AddScoped<ITaskService<MyTaskType>, TechsBCN.Platform.Application.Services.Implementations.TaskService<MyTaskType>>();

RabbitMqMessagingRepository

Su objetivo es publicar mensajes en colas RabbitMQ implementando IMessagingRepository. No tiene método de setup automático, se registra manualmente en el ServicesSetup del proyecto:

services.AddScoped<IMessagingRepository<MyTaskType>, RabbitMqMessagingRepository<MyTaskType>>();

La configuración se define en appsettings.Infrastructure.json:

{
  "RabbitMQ": {
    "HostName": "$(RabbitMQHostName)",
    "UserName": "$(RabbitMQUserName)",
    "Password": "$(RabbitMQPassword)",
    "ExchangeName": "$(RabbitMQExchangeName)",
    "QueueName": "$(RabbitMQQueueName)",
    "SetupSuffix": "$(RabbitMQSetupSuffix)",
    "Port": "$(RabbitMQPort)"
  }
}

Cuando una operación de publicación falla, lanza RabbitMqException. Extiende TechsBcnException para que ErrorMiddleware lo procese correctamente. Las excepciones de infraestructura específicas del proyecto también deben extender TechsBcnException:

public class InfrastructureException(string message) : TechsBcnException(message) { }

MicrosoftGraphEmailRepository

Su objetivo es enviar emails mediante Microsoft Graph API implementando IEmailRepository. No hay que reimplementarlo salvo que el proveedor de email cambie. Cuando los emails incluyen imágenes inline, deben generarse con EmailDataBaseTemplateService.GenerateEmailData, que incrusta las imágenes automáticamente antes de devolver el EmailData.

Se registra con AddScoped en el ServicesSetup del proyecto:

builder.Services.AddScoped<IEmailRepository, MicrosoftGraphEmailRepository>();

La configuración se define en appsettings.Infrastructure.json:

{
  "MicrosoftGraphEmail": {
    "TenantId": "$(MicrosoftGraphEmailTenantId)",
    "ClientId": "$(MicrosoftGraphEmailClientId)",
    "ClientSecret": "$(MicrosoftGraphEmailClientSecret)",
    "SenderUserId": "$(MicrosoftGraphEmailSenderUserId)"
  }
}

SmtpEmailRepository

Su objetivo es enviar emails mediante un servidor SMTP implementando IEmailRepository. Permite que cada proyecto elija el proveedor de email que necesite. No hay que reimplementarlo salvo que el proveedor de email cambie. Cuando EmailData.Sender no está informado, se usa SmtpEmail:Username como remitente. Cuando los emails incluyen imágenes inline, deben generarse con EmailDataBaseTemplateService.GenerateEmailData, que incrusta las imágenes automáticamente antes de devolver el EmailData.

Se registra con AddScoped en el ServicesSetup del proyecto:

builder.Services.AddScoped<IEmailRepository, SmtpEmailRepository>();

La configuración se define en appsettings.Infrastructure.json:

{
  "SmtpEmail": {
    "Host": "$(SmtpEmailHost)",
    "Port": "$(SmtpEmailPort)",
    "SSLEnabled": "$(SmtpEmailSSLEnabled)",
    "Username": "$(SmtpEmailUsername)",
    "Password": "$(SmtpEmailPassword)"
  }
}

AzureBlobStorageRepository

Su objetivo es subir y descargar ficheros mediante Azure Blob Storage implementando IBlobStorageRepository. En la subida genera un identificador único para cada blob y lo almacena con el nombre {guid}-{nombre}, devolviendo el Guid con el que después se recupera. El contenedor se crea automáticamente si no existe.

Se registra con AddScoped en el ServicesSetup del proyecto:

builder.Services.AddScoped<IBlobStorageRepository, AzureBlobStorageRepository>();

La configuración se define en appsettings.Infrastructure.json:

{
  "BlobStorage": {
    "ConnectionString": "$(BlobStorageConnectionString)",
    "Container": "$(BlobStorageContainer)"
  }
}

Cuando una operación de almacenamiento falla, lanza BlobStorageException. Extiende TechsBcnException para que ErrorMiddleware lo procese correctamente.

Helpers (Helpers/)

RestHelper<T>

Su objetivo es hacer llamadas REST desde Infrastructure sin tener que gestionar manualmente la serialización, el logging ni los errores HTTP. Solo debe usarse en la capa Infrastructure — la URL base y las credenciales deben centralizarse siempre en IConfiguration, nunca en el código.

Expone un único método estático:

  • SendRequest(HttpClient client, string url, HttpMethod method, object? data, ILogger? logger) — devuelve (HttpStatusCode StatusCode, T Result). Lanza HttpRequestException si la respuesta no es 2xx.

Para GET y DELETE, data se serializa como query string. Para el resto, en el body como JSON.

Devolver el resultado directamente con .Result:

public IEnumerable<ExternalDto> GetItems(DateTime date) =>
    RestHelper<IEnumerable<ExternalDto>>.SendRequest(
        HttpClient,
        $"{Configuration["ExternalApi:BasePath"]}/items",
        HttpMethod.Get,
        new ItemsFilter { Date = date.ToString("yyyy-MM-dd") },
        logger: Logger
    ).Result;

Cuando hay que verificar el código de respuesta antes de continuar, los errores de comunicación deben traducirse a InfrastructureException:

public void UpdateItem(string reference, UpdateRequest request)
{
    var response = RestHelper<SuccessResponse>.SendRequest(
        HttpClient,
        $"{Configuration["ExternalApi:BasePath"]}/items/{reference}",
        HttpMethod.Put,
        request,
        Logger
    );

    if (response.StatusCode != HttpStatusCode.OK)
        throw new InfrastructureException($"Error updating item {reference}. Status: {response.StatusCode}");
}

Los modelos del proveedor externo no deben exponerse fuera de Infrastructure — el repositorio los mapea al contrato definido en Application.

HttpHeadersExtensions acompaña a RestHelper proporcionando métodos de extensión para trabajar con cabeceras HTTP en las llamadas salientes.

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.0.36 64 9/11/2026
0.0.35 172 8/25/2026
0.0.34 91 8/25/2026
0.0.33 93 8/25/2026
0.0.32 158 7/31/2026
0.0.31 488 7/10/2026
0.0.30 307 6/30/2026
0.0.29 132 6/18/2026
0.0.27 120 6/12/2026
0.0.26 103 6/12/2026
0.0.25 118 6/4/2026
0.0.24 111 6/1/2026
0.0.23 106 6/1/2026
0.0.22 176 5/27/2026