Greencore.Platform.Localization 0.0.1-alpha.2

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

Greencore.Platform.Localization

Localización de mensajes con una única clase inmutable Message para dos formas equivalentes:

  1. Mensajes localizados mediante recursos .resx (Message.FromResource).
  2. Mensajes definidos directamente en código (Message.Create).

Modelo

Message es un dato inmutable (propiedades init: Key, Template, Parameters, Localizer); el comportamiento vive en miembros de extensión. La separación dato/comportamiento permite agregar vocabulario sin tocar el tipo central.

Miembro Ubicación Propósito
Create(...) Estático en Message Crear desde texto literal o plantilla
FromResource(...) Estático en Message Crear desde una clave y un localizador
operator + Estático en Message Concatenar plantillas de mensajes literales con strings o mensajes
Empty Propiedad estática de Message Mensaje vacío; elemento neutro de + y valor por defecto
With(...) MessageExtensions Agregar parámetros y devolver una copia
Resolve(culture) MessageExtensions Obtener el texto final
ForField(...) ValidationMessageExtensions Convenio específico de validación
MessageFactory Clase independiente Localizador compartido para varios mensajes

Create y FromResource expresan cómo se obtiene la plantilla; With agrega los valores. Esa separación evita interpretar un texto como una clave por accidente.

Message además define dos conversiones implícitas:

Message message = "El usuario no tiene autorización."; // string -> Message: siempre texto literal
string text = message;                                  // Message -> string: Resolve()

La conversión desde string aplica en propiedades e invocaciones (AddReason("El stock es insuficiente.");). Para interpretar una cadena como clave de recursos se usa siempre Message.FromResource.

Uso básico

var localizer = new ResourceMessageLocalizer(Messages.ResourceManager);

// Texto literal.
Message message = "El usuario no tiene autorización.";

// Plantilla con parámetros (inmutable: With devuelve copias).
Message minimumLength = Message
    .FromResource("error.min_length", localizer)
    .With("field", "Contraseña")
    .With("min", 8);

string text = minimumLength; // El campo Contraseña debe tener al menos 8 caracteres.

Reutilización y sobrecarga múltiple

With conserva el mensaje original, así las definiciones se reutilizan:

var minimumLength = Message.FromResource("error.min_length", localizer);

var passwordMessage = minimumLength
    .With("field", "Contraseña")
    .With("min", 8);

var usernameMessage = minimumLength
    .With("field", "Usuario")
    .With("min", 3);

// Varios parámetros en una sola copia.
var message = minimumLength.With(
    ("field", "Contraseña"),
    ("min", 8));

Extensiones de vocabulario

MessageExtensions aporta el comportamiento central (With, Resolve); las demás extensiones agregan vocabulario específico sin crecer la API central:

public static class ValidationMessageExtensions
{
    public static Message ForField(this Message message, string field)
        => message.With("field", field);
}

var message = Message
    .FromResource("error.min_length", localizer)
    .ForField("Contraseña")
    .With("min", 8);

Catálogos

public sealed class ErrorMessages(IMessageLocalizer localizer)
{
    public Message Unauthorized => Message.Create("El usuario no tiene autorización.");
    public Message Required(string field)
        => Message.FromResource("error.required", localizer).With("field", field);
    public Message MinimumLength(string field, int minimum)
        => Message.FromResource("error.min_length", localizer)
            .With(("field", field), ("min", minimum));
}

var errors = new ErrorMessages(localizer);
string text = errors.MinimumLength("Contraseña", 8);

Mensaje suelto

Sin recursos ni fábrica, la plantilla nace y muere en el mismo punto:

CultureInfo.CurrentUICulture = CultureInfo.GetCultureInfo("es");

Message suelto = Message.Create(
    "El pedido {order} fue cancelado el {when}.",
    ("order", "A-1002"),
    ("when", new DateTime(2026, 9, 21, 12, 0, 0)));

string text = suelto; // El pedido A-1002 fue cancelado el 21/9/2026 12:00:00.

Fábrica con localizador compartido

MessageFactory conserva el localizador una sola vez; los mensajes resultantes se configuran con With:

var messages = new MessageFactory(localizer);

var message = messages
    .FromResource("error.min_length")
    .With(("field", "Contraseña"), ("min", 8));

Concatenación con +

El operador + concatena plantillas y devuelve un nuevo mensaje literal; los parámetros y la cultura se resuelven hasta el Resolve:

var composed = Message.Create("Hola {name}.", ("name", "Nelson")) + ", bienvenido.";
var reversed = "Saludo: " + Message.Create("hola {name}").With("name", "Nelson");

// Message + Message: union de parámetros; un nombre repetido toma el valor del mensaje derecho.
var joined = Message.Create("{a} + {b} = {sum}.", ("sum", 3)) + " Verificado el {date}.";
string text = joined.With(("a", 1), ("b", 2), ("date", new DateTime(2026, 9, 21)));

Solo los mensajes literales (con plantilla) admiten +; concatenar un mensaje de recurso lanza NotSupportedException. Un string nulo se trata como cadena vacía, como en la concatenación de .NET.

Sustitución única

Cada parámetro se sustituye una sola vez:

  • Con plantilla (Create), Resolve sustituye los marcadores en la plantilla.
  • Con recurso (FromResource), el localizador devuelve el texto ya formateado y Resolve no vuelve a reemplazar.

En ambos casos los valores se convierten con Convert.ToString(value, culture) (por defecto CurrentUICulture), de modo que fechas y números respetan la cultura.

Archivos de recursos

  • resources/Messages.resx: cultura neutra (español).
  • resources/Messages.en.resx: satélite en inglés; .NET genera resources/Messages.en.resources al compilar.
  • resources/Messages.Designer.cs: clase Messages con el ResourceManager (formato de ResXFileCodeGenerator; regenerable desde Visual Studio).

Otros componentes

  • ResourceMessageLocalizer: busca la plantilla en el ResourceManager con la cultura indicada (por defecto CultureInfo.CurrentUICulture) y sustituye los parámetros; si la clave no existe devuelve la propia clave.
  • ICultureContext/CultureContext: culturas activas sin cambiar la configuración global del proceso.
  • SupportedCultures/CultureResolver: culturas admitidas y resolución con cultura de respaldo.
  • ILocalizedFormatter/DateFormatter: formato centralizado de fechas, números y monedas.

El paquete apunta a .NET 10.

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.
  • net10.0

    • No dependencies.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on Greencore.Platform.Localization:

Package Downloads
Greencore.Platform.Errors

Resultados explícitos, errores estructurados, validación y concurrencia asíncrona para .NET.

Greencore.Platform.Validators

Resultados explícitos, errores estructurados, validación y concurrencia asíncrona para .NET.

Greencore.Platform.Nodes

Resultados explícitos, errores estructurados, validación y concurrencia asíncrona para .NET.

Greencore.Platform.Results.Streaming

Resultados explícitos, errores estructurados, validación y concurrencia asíncrona para .NET.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.0.1-alpha.2 68 9/26/2026

Siguiente versión alpha.2 de Greencore.