Skip to content

Conversation

@OmarAglan
Copy link

@OmarAglan OmarAglan commented Oct 9, 2025

This PR implements Core localization infrastructure of the comprehensive localization system for GenHub, establishing the foundational infrastructure for multi-language support. This phase introduces the core services, interfaces, and architecture that will enable seamless translation of the application into multiple languages with runtime language switching.


Core Services & Interfaces

  • ILocalizationService - Primary service interface for accessing localized strings and managing culture
  • LocalizationService - Singleton service implementation with reactive culture change notifications
  • ILanguageProvider - Interface for language discovery and resource management
  • LanguageProvider - Implementation that discovers available languages via satellite assemblies
  • LocalizationOptions - Configuration model for localization behavior
  • LocalizationExtensions - Helper methods for common localization scenarios

Key Features

Reactive Culture Switching - Uses System.Reactive for UI-friendly culture change notifications
Thread-Safe Operations - All culture switching and resource access is thread-safe
Graceful Fallback - Automatically falls back to English for missing translations
Dynamic Language Discovery - Scans for available languages from satellite assemblies
Culture-Aware Formatting - Extensions for dates, numbers, currency, file sizes, etc.
Comprehensive Testing - 44 unit tests with 100% pass rate

🏗️ Architecture & Design

Service Layer

┌─────────────────────────────────────────┐
│         ILocalizationService            │
│  - CurrentCulture: CultureInfo         │
│  - AvailableCultures: List<Culture>    │
│  - CultureChanged: IObservable         │
│  - GetString(key): string              │
│  - SetCulture(culture): Task           │
└─────────────────┬───────────────────────┘
                  │
                  │ depends on
                  ▼
┌─────────────────────────────────────────┐
│         ILanguageProvider               │
│  - DiscoverAvailableLanguages()        │
│  - GetResourceManager(baseName)        │
│  - ValidateCulture(culture)            │
└─────────────────────────────────────────┘

Reactive Pattern

The service implements reactive culture switching using System.Reactive:

// In ViewModels, subscribe to culture changes
_localization.CultureChanged
    .ObserveOn(RxApp.MainThreadScheduler)
    .Subscribe(_ => UpdateLocalizedStrings());

This ensures all UI elements update automatically when the user changes languages.

Thread Safety

  • Uses lock statements for culture switching operations
  • Thread-safe caching of ResourceManager instances
  • Proper synchronization prevents race conditions during concurrent access

Test Coverage

  • 28 LocalizationService tests covering:

    • Culture switching (valid/invalid cultures)
    • String retrieval with/without parameters
    • Fallback behavior
    • Reactive notifications
    • Thread safety
    • Configuration options
    • Disposal pattern
  • 16 LanguageProvider tests covering:

    • Language discovery
    • Culture validation
    • ResourceManager provisioning
    • Caching behavior
    • Error handling

Basic Setup (Dependency Injection)

// In App.axaml.cs or startup configuration
services.AddLocalizationServices(options =>
{
    options.DefaultCulture = "en";
    options.FallbackCulture = "en";
    options.LogMissingTranslations = true;
});

In ViewModels

public class MyViewModel : ViewModelBase
{
    private readonly ILocalizationService _localization;

    public MyViewModel(ILocalizationService localization)
    {
        _localization = localization;
        
        // Subscribe to culture changes for reactive updates
        _localization.CultureChanged
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ => this.RaisePropertyChanged(nameof(WelcomeText)));
    }

    // Property that automatically updates when culture changes
    public string WelcomeText => _localization.GetString("UI.Common.Welcome");
    
    // Formatted string with parameters
    public string GreetingText => _localization.GetString(
        "UI.Common.Greeting", 
        _userService.CurrentUser.Name
    );
}

Changing Languages at Runtime

// Switch to German
await _localization.SetCulture("de");

// Or by CultureInfo
await _localization.SetCulture(new CultureInfo("fr-FR"));

// Get available languages for UI picker
var languages = _localization.AvailableCultures;

Using Extension Methods

// Culture-aware formatting
var formattedDate = _localization.FormatDate(DateTime.Now);
var formattedCurrency = _localization.FormatCurrency(1234.56m);
var formattedFileSize = _localization.FormatFileSize(1024 * 1024 * 500); // "500 MB"

// Try get with fallback
var success = _localization.TryGetString("UI.Common.Save", out var saveText);

// Pluralization support
var itemCount = _localization.GetPluralString(
    count: 5,
    noneKey: "UI.Common.NoItems",
    oneKey: "UI.Common.OneItem", 
    manyKey: "UI.Common.ManyItems"
);

@Skyaero42
Copy link
Contributor

Great start and thank you for your contribution, although I have a number of questions/remarks:

  • Is this a finished PR or are you planning on providing the implementation as well? In case of the latter, it would be better to put it in draft to prevent early on reviews.

  • If it is finished, I think it is a bit barebone. It will need better context on why you have chosen these interfaces

  • Adding new packages should only occur if those packages are actually used in the commit and that there is a valid reasons for using the package. We need to avoid using unnecessary packages, because it will increase the size of the application.

@OmarAglan
Copy link
Author

OmarAglan commented Oct 9, 2025

@Skyaero42 this is WIP pr, the implementation will be added based on these changes in future pr
also a quick question, do i need to add unit tests?

@OmarAglan OmarAglan marked this pull request as draft October 9, 2025 09:37
@Skyaero42
Copy link
Contributor

Yes, unit tests are required. If you review one of Undead's PR, you get an idea of how he does it.

@OmarAglan OmarAglan changed the title Add localization service and language provider interfaces feat(localization): Core localization infrastructure with reactive culture switching Oct 10, 2025
@OmarAglan OmarAglan marked this pull request as ready for review October 10, 2025 23:50
@OmarAglan
Copy link
Author

what can i add next is, if this pr scope allow it:

  1. Create .resx resource file structure in GenHub.Core/Resources/Strings/
  2. Define resource namespaces (e.g., UI.Common, UI.Navigation, Errors.Validation)
  3. Extract existing hardcoded strings to English resource files
  4. Configure GenHub.Core.csproj to build satellite assemblies
  5. Test complete resource loading workflow

@Skyaero42 asked why i used System.Reactive?

System.Reactive is used for CultureChanged notifications because, it Provides a clean, standard observable pattern and Integrates seamlessly with Avalonia's ReactiveUI, and it also Allows ViewModels to react to culture changes without tight coupling, has Thread-safe marshalling to UI thread via ObserveOn(), and from my knowledge its Already commonly used in Avalonia applications.

things to consider:

Both ILocalizationService and ILanguageProvider are registered as singletons because Culture is application-wide state, not per-request and ResourceManager instances should be reused for performance as Satellite assembly discovery happens once at startup and it helps Reduces memory overhead and improves performance

Simple interface Using CultureInfo directly rather than custom models, has Fallback always enabled to English, has Async discovery Language scanning to prevent startup blocking and also Sync string retrieval which makes GetString() synchronous as resources are cached

@ViTeXFTW
Copy link
Contributor

If this is a WIP PR, then it would be helpfull to mark it as a draft. I tried to see if I could do it from my side, but I don't think I can.

@Skyaero42 Skyaero42 marked this pull request as draft October 14, 2025 05:50
@Skyaero42
Copy link
Contributor

If this is a WIP PR, then it would be helpfull to mark it as a draft. I tried to see if I could do it from my side, but I don't think I can.

Done

@OmarAglan OmarAglan force-pushed the Core-localization-system branch from 046665d to 2dc75bc Compare November 6, 2025 02:05
@OmarAglan
Copy link
Author

implemenled Phase 2 of the comprehensive localization system for GenHub, building on the infrastructure established in Phase 1. This phase creates the complete .resx resource file structure with 278 English strings extracted from the existing codebase, configures satellite assembly generation, and validates the end-to-end resource loading workflow.

What's New

Resource File Structure (10 files, 278 strings)

Created organized .resx resource files with English translations:

  • UI.Common.resx (32 strings) - Buttons, states, common actions
  • UI.Navigation.resx (7 strings) - Tab names and navigation labels
  • UI.GameProfiles.resx (25 strings) - Game profile management UI
  • UI.Settings.resx (38 strings) - Settings page labels and options
  • UI.Updates.resx (25 strings) - Update functionality messages
  • Errors.Validation.resx (20 strings) - Input validation errors
  • Errors.Operations.resx (38 strings) - Operation error messages
  • Messages.Success.resx (27 strings) - Success confirmations
  • Messages.Confirmations.resx (28 strings) - User confirmation dialogs
  • Tooltips.resx (38 strings) - UI element tooltips

Key Features

Hierarchical Organization - Resources organized by functional area
Translator-Friendly - All strings have contextual comments
Format String Support - Parameterized strings with {0}, {1} placeholders
Strongly-Typed Access - StringResources class for compile-time safety
Satellite Assembly Ready - Configured for culture-specific translations
Full Test Coverage - 15 integration tests validating resource loading
Comprehensive Documentation - Complete guide for developers and translators


Files Changed

New Files (13 files, 3,428 lines)

Resource Files (10 files, 2,780 lines)

  • GenHub.Core/Resources/Strings/UI.Common.resx (32 strings)
  • GenHub.Core/Resources/Strings/UI.Navigation.resx (7 strings)
  • GenHub.Core/Resources/Strings/UI.GameProfiles.resx (25 strings)
  • GenHub.Core/Resources/Strings/UI.Settings.resx (38 strings)
  • GenHub.Core/Resources/Strings/UI.Updates.resx (25 strings)
  • GenHub.Core/Resources/Strings/Errors.Validation.resx (20 strings)
  • GenHub.Core/Resources/Strings/Errors.Operations.resx (38 strings)
  • GenHub.Core/Resources/Strings/Messages.Success.resx (27 strings)
  • GenHub.Core/Resources/Strings/Messages.Confirmations.resx (28 strings)
  • GenHub.Core/Resources/Strings/Tooltips.resx (38 strings)

Helper Classes (1 file, 64 lines)

  • GenHub.Core/Resources/Strings/StringResources.cs - Strongly-typed resource namespace constants

Tests (1 file, 384 lines)

  • GenHub.Tests/GenHub.Tests.Core/Resources/StringResourcesTests.cs - Integration tests for resource loading

Documentation (1 file, 200 lines)

  • docs/localization-resources-guide.md - Complete resource usage guide

Modified Files (4 files)

Project Configuration

  • GenHub.Core/GenHub.Core.csproj - Added resource generation and satellite assembly configuration

Service Updates

  • GenHub.Core/Interfaces/Localization/ILocalizationService.cs - Added GetString(resourceSet, key) overloads
  • GenHub.Core/Services/Localization/LocalizationService.cs - Implemented resource set support

Test Updates

  • GenHub.Tests/GenHub.Tests.Core/Services/Localization/LocalizationServiceTests.cs - Added tests for new overloads

Architecture & Design

Resource Organization

GenHub.Core/Resources/Strings/
├── UI.Common.resx              → GenHub.Core.Resources.Strings.UI.Common
├── UI.Navigation.resx          → GenHub.Core.Resources.Strings.UI.Navigation
├── UI.GameProfiles.resx        → GenHub.Core.Resources.Strings.UI.GameProfiles
├── UI.Settings.resx            → GenHub.Core.Resources.Strings.UI.Settings
├── UI.Updates.resx             → GenHub.Core.Resources.Strings.UI.Updates
├── Errors.Validation.resx      → GenHub.Core.Resources.Strings.Errors.Validation
├── Errors.Operations.resx      → GenHub.Core.Resources.Strings.Errors.Operations
├── Messages.Success.resx       → GenHub.Core.Resources.Strings.Messages.Success
├── Messages.Confirmations.resx → GenHub.Core.Resources.Strings.Messages.Confirmations
└── Tooltips.resx               → GenHub.Core.Resources.Strings.Tooltips

Resource Key Naming Convention

Uses hierarchical dot notation for clarity:

UI.Common.Button.Save           → "Save"
UI.Common.Button.Cancel         → "Cancel"
UI.GameProfiles.Create.Title    → "Create New Profile"
Errors.Validation.RequiredField → "{0} is required."
Messages.Confirmations.Delete   → "Are you sure you want to delete {0}?"

Project Configuration

Added to GenHub.Core.csproj:

<PropertyGroup>
  <GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
</PropertyGroup>

<ItemGroup>
  <EmbeddedResource Update="Resources\Strings\*.resx">
    <Generator>ResXFileCodeGenerator</Generator>
    <CustomToolNamespace>GenHub.Core.Resources.Strings</CustomToolNamespace>
  </EmbeddedResource>
</ItemGroup>

This configures:

  • Satellite assembly generation for culture-specific resources
  • Automatic code generation for strongly-typed resource access
  • Custom namespace for generated resource classes

Testing

Test Coverage

Added 15 integration tests, all passing ✅

Tests validate:

  • ✅ All 10 resource sets are properly embedded
  • ✅ ResourceManager creation for each namespace
  • ✅ String retrieval from each resource set
  • ✅ LocalizationService integration with resource sets
  • ✅ Format string parameter substitution
  • ✅ ResourceManager caching
  • ✅ Multiple strings per resource set
  • ✅ Resource set constant correctness

📖 Usage Examples

Basic String Retrieval

public class MyViewModel : ViewModelBase
{
    private readonly ILocalizationService _localization;

    public MyViewModel(ILocalizationService localization)
    {
        _localization = localization;
    }

    public void SaveProfile()
    {
        // Get a simple string
        var saveText = _localization.GetString(
            StringResources.UiCommon, 
            "Button.Save"
        );
        // Returns: "Save"
    }
}

Format Strings with Parameters

// String in Errors.Validation.resx: "RequiredField" = "{0} is required."
var errorMessage = _localization.GetString(
    StringResources.ErrorsValidation,
    "RequiredField",
    "Profile Name"
);
// Returns: "Profile Name is required."

Using StringResources Constants

// Strongly-typed resource set names prevent typos
var confirmDelete = _localization.GetString(
    StringResources.MessagesConfirmations,  // Compile-time checked!
    "DeleteProfile",
    profileName
);
// Returns: "Are you sure you want to delete {profileName}?"

Real-World ViewModel Example

public class SettingsViewModel : ViewModelBase
{
    private readonly ILocalizationService _localization;

    public SettingsViewModel(ILocalizationService localization)
    {
        _localization = localization;
        
        // Subscribe to culture changes for reactive updates
        _localization.CultureChanged
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ => UpdateLocalizedProperties());
    }

    // Property bound to UI
    public string ThemeLabel => _localization.GetString(
        StringResources.UiSettings,
        "Theme.Label"
    );
    
    // Property bound to UI
    public string LanguageLabel => _localization.GetString(
        StringResources.UiSettings,
        "Language.Label"
    );

    private void UpdateLocalizedProperties()
    {
        // Notify UI that all localized properties have changed
        this.RaisePropertyChanged(nameof(ThemeLabel));
        this.RaisePropertyChanged(nameof(LanguageLabel));
        // ... more properties
    }
}

📚 Resource File Structure

Sample: UI.Common.resx

<data name="Button.Save" xml:space="preserve">
  <value>Save</value>
  <comment>Button text for saving changes</comment>
</data>

<data name="Status.Loading" xml:space="preserve">
  <value>Loading...</value>
  <comment>Displayed while content is loading</comment>
</data>

<data name="Action.Delete" xml:space="preserve">
  <value>Delete</value>
  <comment>Action to delete an item</comment>
</data>

Sample: Errors.Validation.resx

<data name="RequiredField" xml:space="preserve">
  <value>{0} is required.</value>
  <comment>Generic validation error for required fields. {0} = field name</comment>
</data>

<data name="InvalidPath" xml:space="preserve">
  <value>The path '{0}' is not valid.</value>
  <comment>Path validation error. {0} = the invalid path</comment>
</data>

<data name="ProfileNameTooLong" xml:space="preserve">
  <value>Profile name must be {0} characters or less.</value>
  <comment>Profile name length validation. {0} = maximum length</comment>
</data>

🔍 String Extraction Coverage

Strings were systematically extracted from:

ViewModels ✅

  • MainViewModel - Navigation, profile creation, status messages
  • SettingsViewModel - All settings labels, theme options, validation
  • GameProfileLauncherViewModel - Profile loading, game scanning messages
  • UpdateNotificationViewModel - Update checks, download progress, installation
  • ContentBrowserViewModel - Search, filter labels

Services ✅

  • LocalizationService - Error messages, culture validation
  • LanguageProvider - Discovery errors, logging messages

Constants ✅

  • UiConstants - UI labels and messages
  • ValidationLimits - Validation error templates

What Was NOT Extracted

The following remain in English as per best practices:

  • ❌ Debug/trace log messages
  • ❌ Developer exception messages
  • ❌ Technical identifiers and enum names
  • ❌ Code comments and documentation

Translator-Friendly Features

1. Contextual Comments

Every string includes a comment explaining:

  • Where it's used in the UI
  • What parameters represent (if any)
  • Character length constraints (if applicable)

2. Logical Grouping

Related strings are grouped together:

Button.Save
Button.Cancel
Button.OK
Button.Apply

3. Clear Naming

Key names are self-documenting:

  • UI.GameProfiles.Create.Title clearly indicates a title for profile creation
  • Errors.Validation.RequiredField is obviously a validation error

4. Format Placeholders

Numbered placeholders are documented:

<comment>
  {0} = profile name
  {1} = game name
  Example: "Profile 'MyProfile' created for The Sims 4"
</comment>

5. Translation Tool Support

.resx files work with:

  • ResXManager (recommended, free, cross-platform)
  • Visual Studio Resource Editor
  • Rider Resource Editor
  • Any text editor (XML format)

🚀 Satellite Assembly Generation

How It Works

When culture-specific translations are added (Phase 8-9):

GenHub.Core/Resources/Strings/
├── UI.Common.resx              → Embedded in GenHub.Core.dll (English)
├── UI.Common.de.resx           → German satellite: de/GenHub.Core.resources.dll
├── UI.Common.fr.resx           → French satellite: fr/GenHub.Core.resources.dll
└── UI.Common.es.resx           → Spanish satellite: es/GenHub.Core.resources.dll

Build output structure:

bin/Debug/net8.0/
├── GenHub.Core.dll              (English resources embedded)
├── de/
│   └── GenHub.Core.resources.dll (German satellite)
├── fr/
│   └── GenHub.Core.resources.dll (French satellite)
└── es/
    └── GenHub.Core.resources.dll (Spanish satellite)

Current Status

  • ✅ Configuration complete
  • ✅ Infrastructure ready
  • ⏳ Satellite assemblies will be generated when translations are added

Metrics

Metric Value
Resource Files 10
Total Strings 278
Lines of Resources 2,780
Test Coverage 15 tests, 100% pass
Resource Categories UI (4), Errors (2), Messages (2), Tooltips (1), Navigation (1)
Average Strings per File 27.8

Additional Resources Or Docs


Translation Workflow (For Future)

When adding new languages:

  1. Copy English .resx files and rename with culture code:

    • UI.Common.resxUI.Common.de.resx (German)
    • UI.Common.resxUI.Common.fr.resx (French)
  2. Translate values (keep keys unchanged):

    <!-- UI.Common.de.resx -->
    <data name="Button.Save" xml:space="preserve">
      <value>Speichern</value>
    </data>
  3. Build project - Satellite assemblies auto-generate

  4. Test - Language appears in settings automatically


@OmarAglan OmarAglan marked this pull request as ready for review November 6, 2025 03:34
@OmarAglan
Copy link
Author

request Review From @Skyaero42 and @undead2146 and @ViTeXFTW

Copy link
Member

@undead2146 undead2146 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good so far, I don't have much experience with localisation hence I cannot give a deeper review than just the surface level comments

@undead2146
Copy link
Member

Is this still being worked on @OmarAglan?

@undead2146
Copy link
Member

@OmarAglan I will be putting this in draft considering no new updates have been made

@undead2146 undead2146 marked this pull request as draft November 28, 2025 22:23
@OmarAglan OmarAglan force-pushed the Core-localization-system branch 2 times, most recently from 770653b to 9bda372 Compare December 6, 2025 17:16
@OmarAglan
Copy link
Author

Added 159 missing user-facing strings across 12 resource files

comprehensive string extraction audit for GenHub's localization system. The initial resource file had 278 strings, i scanned the entire codebase to identify and add all remaining user-facing strings, bringing the total to 437 localized strings across 12 resource files.

New Resource Files

  1. UI.Tools.resx (32 strings)

    • Tool plugin management UI
    • Tool installation/uninstallation messages
    • Tool settings and configuration
    • Tool validation messages
  2. UI.Downloads.resx (18 strings)

    • Download status messages
    • Download progress labels
    • Download error messages
    • Queue management UI

@undead2146
Copy link
Member

@OmarAglan is this PR ready for review?

@OmarAglan
Copy link
Author

@OmarAglan is this PR ready for review?

Yes
Once you do i will apply any required modification, and its good to go
Next pr soon
I just got busy lately sorry about that

@undead2146 undead2146 marked this pull request as ready for review December 20, 2025 20:53
Introduces ILanguageProvider and ILocalizationService interfaces to support resource management and runtime language switching. Also adds System.Reactive package to enable reactive culture change notifications.
Introduces LocalizationOptions for configuring localization behavior and LanguageProvider for discovering available languages, managing resource managers, and validating cultures. These additions support improved localization management and extensibility in the application.
Introduces LocalizationService for runtime language switching, resource management, and reactive culture updates. Adds LocalizationExtensions with culture-aware formatting and utility methods for dates, numbers, currency, percentages, file sizes, pluralization, and culture info.
Introduces LocalizationServicesModule for registering localization-related services and options via dependency injection. Provides extension methods for IServiceCollection to add localization services with optional configuration, Added System.Reactive to Directory.Packages.props and removed explicit version from GenHub.Core.csproj to centralize package version management.
Introduces LanguageProviderTests and LocalizationServiceTests to verify the behavior of language discovery, culture validation, resource management, and localization service features including culture changes, string retrieval, and error handling.
Introduced new .resx resource files for error messages, validation, confirmations, success messages, tooltips, and UI labels to support application localization. Also added documentation describing the localization system design.
Added GenerateSatelliteAssembliesForCore property to support satellite assemblies. Configured .resx files in Resources/Strings as embedded resources with code generation and a custom namespace.
Introduces the StringResources static class to provide strongly-typed access to resource file base names used in the localization system. This improves maintainability and reduces errors when referencing string resources throughout the application.
Extended LocalizationService to allow specifying a resource set when retrieving localized strings. This adds overloads for GetString that accept a resource set parameter, improving flexibility and enabling localization from multiple resource sets. Enhanced logging now includes the resource set for better traceability.
Added comprehensive integration tests for string resource loading and localization infrastructure in StringResourcesTests.cs. Updated localization system architecture documentation with formatting and clarity improvements. Introduced a new localization resources guide detailing resource file structure, naming conventions, usage, and best practices for developers and translators.
Introduces new GetString overloads in ILocalizationService to support retrieving localized strings from specific resource sets, with and without formatting arguments. Updates related test to use explicit object array casting for null arguments.
Reduced the required minimum number of strings in each resource file from 10 to 5 in StringResourcesTests. This change accounts for resource sets that naturally have fewer entries, such as UI.Navigation.
Introduces UI.Tools.resx containing localized strings for the Tools tab, including labels, buttons, status messages, error messages, tooltips, and dialog titles to support tool plugin management in GenHub.
Introduces UI.Downloads.resx containing localized strings for the Downloads tab, including page titles, section headers, download categories, and status messages to support UI text management and localization.
Expanded resource files with additional UI strings for buttons, status messages, section headers, labels, placeholders, and error messages. These changes improve localization and provide more descriptive text for game profiles, navigation, and settings sections.
Introduced several new resource strings for the update dialog, including messages for update availability, release notes, default update notes, up-to-date status, version readiness, and progress percentage. These additions support improved user communication during the update process.
Added service availability, file system, and tool-related error messages to Errors.Operations.resx. Introduced profile validation messages to Errors.Validation.resx. Updated StringResources.cs with new resource base names for tools and downloads UI.
Escaped ampersands as &amp; in UI.Downloads.resx, UI.GameProfiles.resx, and UI.Navigation.resx to ensure correct XML and UI rendering. Updated localization-resources-guide.md to document new resource files, string counts, and recent changes to resource management.
Copilot AI review requested due to automatic review settings December 23, 2025 16:19
@OmarAglan OmarAglan force-pushed the Core-localization-system branch from ecf94f5 to 8367163 Compare December 23, 2025 16:19
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a comprehensive core localization infrastructure for GenHub, establishing the foundation for multi-language support with reactive culture switching. The implementation uses .NET resource files (.resx) with satellite assemblies following Avalonia's recommended approach.

Key Changes:

  • Introduces ILocalizationService and LocalizationService for runtime language switching with reactive notifications
  • Implements ILanguageProvider and LanguageProvider for satellite assembly discovery and resource management
  • Creates 12 resource files with 437 English strings organized by functional area
  • Provides comprehensive test coverage with 44 unit tests
  • Includes detailed architecture and usage documentation

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated no comments.

Show a summary per file
File Description
GenHub.Core/Interfaces/Localization/ILocalizationService.cs Core service interface for localization with culture management and reactive updates
GenHub.Core/Interfaces/Localization/ILanguageProvider.cs Interface for language discovery and ResourceManager provisioning
GenHub.Core/Services/Localization/LocalizationService.cs Singleton service implementation with thread-safe operations
GenHub.Core/Services/Localization/LanguageProvider.cs Implementation for satellite assembly discovery and caching
GenHub.Core/Models/Localization/LocalizationOptions.cs Configuration model with fallback and logging options
GenHub.Core/Extensions/Localization/LocalizationExtensions.cs Helper methods for culture-aware formatting
GenHub.Core/Resources/Strings/*.resx 12 resource files with organized English strings
GenHub.Core/Resources/Strings/StringResources.cs Constants for type-safe resource set access
GenHub/Infrastructure/DependencyInjection/LocalizationServicesModule.cs DI registration with configuration support
GenHub.Tests.Core/Services/Localization/*.cs Comprehensive unit tests (28 + 16 tests)
GenHub.Tests.Core/Resources/StringResourcesTests.cs Integration tests for resource loading
docs/architecture/localization-system-design.md Detailed architecture design document
docs/localization/localization-resources-guide.md Resource organization and usage guide

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Moved and deduplicated Dispose pattern in LocalizationService. Minor formatting and ordering fixes in LanguageProvider and LocalizationExtensions. Cleaned up and condensed localization system architecture documentation.
Eliminated GetString overloads that did not require a resource set from ILocalizationService and LocalizationService. Updated all usages and related tests to explicitly specify the resource set, improving clarity and reducing ambiguity in localization calls.
@OmarAglan
Copy link
Author

Rebased And Updated, Can You Take Another Look @undead2146

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants