| Clean Architecture Toolkit for .NET | |||||
|
Clean Architecture Toolkit is a clean, modular architecture foundation for .NET applications. It embraces SOLID principles and focuses on maintainability, testability, and scalability through clear boundaries and pluggable design. |
|
||||
|
| HOME | MODULE OVERVIEW | DEMO | |
|||||
Cat.Localizations
Cat.Localizations defines a contract for looking up localized strings by key, so the rest of your app doesn’t need to know which localization provider sits behind it.
The module ships with a no-op implementation that returns the key as-is, with placeholders filled in. It’s a safe default, and handy in tests. Plug in your own ICatLocalizer backed by resource files, a translation service, or whatever fits your app, when you need real localization.
Table of contents
NuGet packages
| Package | Role | Install | Downloads |
|---|---|---|---|
| Cat.Localizations.Abstractions | Contracts | dotnet add package gmarginet.Cat.Localizations.Abstractions |
|
| Cat.Localizations | Implementation | dotnet add package gmarginet.Cat.Localizations |
Namespaces
| Namespace | What it holds |
|---|---|
| Cat.Localizations.Abstractions | The ICatLocalizer interface. |
| Cat.Localizations | The no-op localizer and the module registration. |
Dependencies
| Module | Why Cat.Localizations needs it |
|---|---|
| Cat.Extensions | Small helpers for service registration. |
Usage
Register the module
Call AddCatNoLocalizationLocalizer to register ICatLocalizer as a singleton, backed by the no-op implementation.
using Cat.Localizations.Extensions;
services.AddCatNoLocalizationLocalizer();
Look up a string
Resolve the localizer and use its indexers. One takes a key. The other takes a key and the values for its placeholders.
using Cat.Localizations.Abstractions;
var localizer = serviceProvider.GetRequiredService<ICatLocalizer>();
var title = localizer["Order.Title"];
var message = localizer["Order.Created", orderId];
The no-op implementation returns the key itself. It only fills in placeholders when the key contains them, in the order of the arguments:
localizer["Order.Title"]; // "Order.Title"
localizer["Order {OrderId} was created", 42]; // "Order 42 was created"
Inject the localizer into the classes that need text:
public class OrderMessages
{
private readonly ICatLocalizer _localizer;
public OrderMessages(ICatLocalizer localizer)
{
_localizer = localizer;
}
public string Created(int orderId) => _localizer["Order.Created", orderId];
}
Write your own localizer
Implement ICatLocalizer and register it instead of the no-op one. Fill the placeholders of the localized text from arguments, in order.
using Cat.Localizations.Abstractions;
using Cat.String.Extensions;
public class ResourceCatLocalizer : ICatLocalizer
{
private readonly IStringProvider _stringProvider;
public ResourceCatLocalizer(IStringProvider stringProvider)
{
_stringProvider = stringProvider;
}
public string this[string key] => _stringProvider.Get(key) ?? key;
public string this[string key, params object[] arguments] => this[key].NamedFormat(arguments);
}
services.AddSingleton<ICatLocalizer, ResourceCatLocalizer>();
Errors and exceptions
The contract doesn’t define errors. A localizer returns a string for every key, and it doesn’t use responses.
| Situation | What you get |
|---|---|
| The no-op localizer gets any key | The key itself. It never fails on an unknown key. |
| The key has more placeholders than arguments | A FormatException from the no-op localizer. |
| The key has fewer placeholders than arguments | The extra arguments are ignored. |
ICatLocalizer isn’t registered |
An InvalidOperationException from the service provider when you resolve it. |
What your own localizer does for a missing key is up to you. Returning the key, as in the example, makes a missing translation easy to spot in the UI.