Skip to content
This repository has been archived by the owner on Nov 29, 2018. It is now read-only.

Decouple StringLocalizer / HtmlLocalizer from types to make Shared Resources possible #153

Closed
JoeOM opened this issue Nov 26, 2015 · 14 comments

Comments

@JoeOM
Copy link

JoeOM commented Nov 26, 2015

Hi

I had localization working perfectly with beta8 but in RC1 it is not working.

I have two resource files under Resources folder:

  1. Example.Resources.Example.Startup.en-AU.resx
  2. Example.Resources.Example.Startup.zh-CHS.resx

I also have the following resource related configured in Startup:

services.AddLocalization(l => l.ResourcesPath = "Resources");

...

var requestLocalizationOptions = new RequestLocalizationOptions 
            {   
                SupportedCultures = new List<CultureInfo> 
                { 
                    new CultureInfo("en-AU"),
                    new CultureInfo("zh-CHS")
                }, 
                SupportedUICultures = new List<CultureInfo> 
                {
                    new CultureInfo("en-AU"),
                    new CultureInfo("zh-CHS")
                } 
            }; 

app.UseRequestLocalization(requestLocalizationOptions,  new RequestCulture("en-AU"));

I only use IStringLocalizer<Startup> injected into my views / controllers but it just show me the Key and not the Value even though my request header accept language is en-AU, however if I add a third resource file (Example.Resources.Example.Startup.resx) to Resources folder without the culture at the end it works by providing a Value instead of the Key.

I use the very odd weird pattern of having to have a class to use shared resources (shared resources across files types etc are the way it works in the real world), so I am forced to use Startup or create an EMPTY class! It seems that the designer of how the new localization works has never worked with multicultural applications...

Why not make it possible to pass in a resource name instead of making it type specific!? Really really odd and really limiting. I think there will be a lot of people complaining in the future when this is RTM!

Please guys test it and fix it!

@damienbod
Copy link

I agree with Joe.

This should be fixed. A good solution for shared resources is required.

Greetings Damien

@boyarincev
Copy link

I encountered this problem too in my application.
I've tried to check LocalizationWebSite and getting localized string from Resource Manager dosen't work too there.

As JoeOM noticed if use resources without specifying culture in the name, then all work fine.

@ryanbrandenburg
Copy link
Contributor

@JoeOM and @boyarincev, it sounds like you may be running into DNX 3047, whereby Resources aren't available if you launch your app from VS. Could you try running your sites from the command line with "dnx web" and let me know if you still have trouble?

@JoeOM
Copy link
Author

JoeOM commented Dec 1, 2015

Hi Ryan

It is correct, I am starting the app from within Visual Studio which is how most people in development would start their site. It is therefore crucial for it to work, so this is a bug and need to be fixed. It seems to be due to DNX 3047 which was raised before RC1, so why RC1 has gone out without this working is another question.

To be honest, localization does not work well. It is in dire need of proper testing and lots of it. I know that this is very generalised and as programmers we need to be more specific, but that is the general feeling I get while working with it since Beta 7.

It is also not geared towards the real world problem of shared resources and funny things like creating an empty class to work around that simply does not cut it.

Give us a resource by name and not this type specific limited solution. Nobody will enjoy having to deal with hundreds of files let alone one for each language multiplied by hundreds!

It is back to the drawing board on this one I'm afraid.

@boyarincev
Copy link

By launching from command line, all works fine

@damienbod
Copy link

@JoeOM @ryanbrandenburg @boyarincev I've just created a global issue for this, could you give your views here?

dotnet/aspnetcore#1142

Greetings Damien

@Eilon
Copy link
Member

Eilon commented Dec 1, 2015

This is indeed the issue that @ryanbrandenburg pointed out. It is in the process of being fixed, but the fix is complex and involves rewriting large parts of DNX.

@JoeOM
Copy link
Author

JoeOM commented Dec 1, 2015

Eilon, does it mean that the issue around shared resources not being possible without funny magic is also in the process of being fixed?

@Eilon
Copy link
Member

Eilon commented Dec 2, 2015

Sorry I'm not sure exactly what "shared resources across files types" means. In general common resources would be in their own resource set, which is identifiable via some name. And they can be shared amongst many components. And then each component would likely have its own resource set as well.

Can you share more info about what you tried, what the expectations were, and what didn't work?

@JoeOM
Copy link
Author

JoeOM commented Dec 3, 2015

Hi Eilon

I was writing in context of above comments. I was referring to the issue of having to declare or use a class type to use resources. What you were describing as shared resources would be nice if it was possible by default currently in ASP.Net 5 Localization. It unfortunately is not since there is no way of passing the base name (name without culture specific details) of the resx file to the StringLocalizer constructor. You have to specify a type like StringLocalizer which then corresponds to a resx file name (full name of type).

This is problematic since you now tie the resx to a type, which is NOT how it should be for shared resources!

This default behaviour seems to be by design which is flawed, because now you need to create a class for no real purpose at all but to use resources across classes. Now I guess I could use a StringLocalizer or StringLocalizer everywhere but that is also not ideal as it would confuse people and it just seems like a hack. StringLocalizer / HtmlLocalizer should also have a non generic version with a constructor accepting an identifier string...

@Eilon
Copy link
Member

Eilon commented Dec 3, 2015

Re-opening so the team can review in the next bug review meeting (next week).

@Eilon Eilon reopened this Dec 3, 2015
@JoeOM
Copy link
Author

JoeOM commented Dec 3, 2015

:-)

@JoeOM JoeOM changed the title Localization no longer works after updating to rc1 Decouple StringLocalizer / HtmlLocalizer from types to make Shared Resources possible Dec 10, 2015
@DamianEdwards
Copy link
Member

You absolutely can get a resource of any name you like by using the IStringLocalizerFactory type directly. The IStringLocalizer<T> is simply a convenience type that is opinionated about where it looks for resources (namely, it uses the name of the type T). Same applies for IHtmlLocalizerFactory and IHtmlLocalizer<T>. Also, IViewLocalizer is similar to the "T" types in that it's simply an opinionated way to find resources, in this case by using the view file's project relative path.

To do it manually:

public class MyController : Controller
{
    private readonly IStringLocalizer _localizer;

    public MyController(IStringLocalizerFactory localizerFactory)
    {
        _localizer = localizerFactory.Create("Use.Whatever.Name.Here.You.Like");
    }

    public IActionResult Index()
    {
        ViewData["Message"] = _localizer["My default welcome message"];
    }
}

@JoeOM
Copy link
Author

JoeOM commented Dec 15, 2015

Brilliant, thank you!!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants