skip to Main Content

In .net 8 razor, how would I go about having a shared localization resource in my project?

Currently, I have the following layout:

enter image description here

This works for the index page, but I also want resources from RShared.resx (poorly named, but this is an example).

_ViewImports:

@using SE.Web
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@namespace SE.Web.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

program.cs

builder.Services.AddLocalization(options => options.ResourcesPath = "LocalizationResources");

builder.Services.AddRazorPages(options =>
{
    options.Conventions.Add(new CustomRouteModelConvention());
}).AddViewLocalization();

2

Answers


  1. Chosen as BEST ANSWER

    Using the answer from Qing Guo, here was the final over-engineered version:

    ServicesLocalizerService

    public class LocalizerService
    {
        Dictionary<string, LocalizerResource> _localizedFactories = new Dictionary<string, LocalizerResource>();
    
        public IStringLocalizerFactory Factory { get; }
    
        public LocalizerService(IStringLocalizerFactory factory)
        {
            Factory = factory;
        }
    
        public LocalizerResource GetLocalizer<T>()
        {
            var res = new LocalizerResource(Factory, typeof(T));
            _localizedFactories.Add(nameof(T), res);
    
            return res;
        }
    
        public string GetValue(string resource, string key)
        {
            if (_localizedFactories.ContainsKey(resource))
                return _localizedFactories[resource][key];
            else
                return this[resource][key];
        }
    
        public LocalizerResource this[string resource]
        {
            get
            {
                if (_localizedFactories.ContainsKey(resource))
                    return _localizedFactories[resource];
                else
                {
                    var res = new LocalizerResource(Factory, resource);
                    _localizedFactories.Add(resource, res);
                    return res;
                }
            }
        }
    }
    

    ResourcesRSharedResources (same directory as shared resx file)

    public class RSharedResources
    {
    }
    

    ResourcesLocalizerResource (same directory as shared resx files)

    public class LocalizerResource
    {
        public string Name { get; set; }
        public IStringLocalizer Localizer { get; set; }
        public LocalizerResource(IStringLocalizerFactory factory, Type T)
        {
    
            var assembly = new AssemblyName(T.Assembly.FullName);
            Name = T.Name;
            Localizer = factory.Create(Name, assembly.Name);
        }
    
        public LocalizerResource(IStringLocalizerFactory factory, string name, string assemblyName = "")
        {
            if (string.IsNullOrEmpty(assemblyName)) assemblyName = this.GetType().Assembly.FullName;
            this.Localizer = factory.Create(name, assemblyName);
        }
    
        public string this[string key] => Localizer[key];
    }
    

    Program.cs

    builder.Services.AddSingleton<LocalizerService>();
    

    Potential uses in razor pages:

    @inject LocalizerService sharedLocalizer
    @{
    //option 1: assign new variable to specific localizer
        var localizeTest = sharedLocalizer["RSharedResources"];
    }
    //and use it like this
    @localizeTest["Greeting"]
    
    //option 2: use the sharedLocalizer to specify both
    @sharedLocalizer["RSharedResources"]["Greeting"]
    

  2. how would I go about having a shared localization resource in my
    project

    Try to use the IStringLocalizerFactory interface to create IStringLocalizer instances, then register the Service with the DI system, below is a demo, you can refer to it.

    1. Add a new class file to the Resources folder(your LocalizationResources folder) named RSharedResources. It is an empty class.
     public class RSharedResources
     {
     }
    

    2.Add a new folder to the root of the project named Services. Add a C# class file to the folder named RSharedService.cs with the following code:

    public class RSharedService
    {
        private readonly IStringLocalizer localizer;
        public RSharedService(IStringLocalizerFactory factory)
        {
            var assemblyName = new AssemblyName(typeof(RSharedResources).GetTypeInfo().Assembly.FullName);
            localizer = factory.Create(nameof(RSharedResources), assemblyName.Name);
        }
    
        public string Get(string key)
        {
            return localizer[key];
        }
    }
    

    3.Register the RSharedService in Program.cs:

    builder.Services.AddSingleton<RSharedService>();
    

    4.Add a resource file to the Resources folder named RSharedResources.en.resx.

      Greeting      Hello afternoon!
    

    5.Inject the RSharedService into the index page:

    @using yourprojectname.Services
    @inject RSharedService localizer
    @localizer.Get("Greeting")
    
    1. Pass the culture query parameter with the value set to de : ?culture=en

    Structure:

    enter image description here

    result:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search