Greencore.Platform.Localization
0.0.1-alpha.2
dotnet add package Greencore.Platform.Localization --version 0.0.1-alpha.2
NuGet\Install-Package Greencore.Platform.Localization -Version 0.0.1-alpha.2
<PackageReference Include="Greencore.Platform.Localization" Version="0.0.1-alpha.2" />
<PackageVersion Include="Greencore.Platform.Localization" Version="0.0.1-alpha.2" />
<PackageReference Include="Greencore.Platform.Localization" />
paket add Greencore.Platform.Localization --version 0.0.1-alpha.2
#r "nuget: Greencore.Platform.Localization, 0.0.1-alpha.2"
#:package Greencore.Platform.Localization@0.0.1-alpha.2
#addin nuget:?package=Greencore.Platform.Localization&version=0.0.1-alpha.2&prerelease
#tool nuget:?package=Greencore.Platform.Localization&version=0.0.1-alpha.2&prerelease
Greencore.Platform.Localization
Localización de mensajes con una única clase inmutable Message para dos formas equivalentes:
- Mensajes localizados mediante recursos
.resx(Message.FromResource). - 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),Resolvesustituye los marcadores en la plantilla. - Con recurso (
FromResource), el localizador devuelve el texto ya formateado yResolveno 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 generaresources/Messages.en.resourcesal compilar.resources/Messages.Designer.cs: claseMessagescon elResourceManager(formato deResXFileCodeGenerator; regenerable desde Visual Studio).
Otros componentes
ResourceMessageLocalizer: busca la plantilla en elResourceManagercon la cultura indicada (por defectoCultureInfo.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 | Versions 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. |
-
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.