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

Support localization resources in a separate assembly #8739

Closed
fabercs opened this issue Nov 19, 2018 · 18 comments
Closed

Support localization resources in a separate assembly #8739

fabercs opened this issue Nov 19, 2018 · 18 comments
Assignees
Labels

Comments

@fabercs
Copy link

fabercs commented Nov 19, 2018

Is this a Bug or Feature request?:

It is a feature, but not sure if it exists or not

Description of the problem:

I am trying to move the localization resources(MyProject.Web.Resources) in MyProject.Web asp.net core mvc project to another separate MyProject.Resources project. I guess it is only doable for a shared resource, however, by doing this, I still want to make use of the IStringLocalizer work in my views and controllers. It seems it does not right now.

Version of Microsoft.AspNetCore.Mvc

@mkArtakMSFT
Copy link
Member

Hi. It looks like this is a question about how to use ASP.NET Core. While we do our best to look through all the issues filed here, to get a faster response we suggest posting your questions to StackOverflow using the asp.net-core-mvc tag.

@mkArtakMSFT
Copy link
Member

@ryanbrandenburg, can you please answer this question when you get time? Thanks!

@hishamco
Copy link
Contributor

You can use ResourceLocationAttribute

@fabercs
Copy link
Author

fabercs commented Nov 22, 2018

@mkArtakMSFT There is a post on this subject at stackoverflow, however there is not a real answer, check the link

@ryanbrandenburg , @hishamco I did lots of thing but I couldn't get it work. Is there any real world application that works like this way? I know resources and pages or classes follow namespace convention, but I couldn't understand how using an assemblyInfo solves this.

Here what I did;

  • Moved Resources folder in Web project to new MyProject.Resources class library project as shown my previous post. So, all resources wrapped inside a Resource folder.

  • Added an AssemblyInfo.cs in the root of MyProject.Resources and added following line;
    [assembly: ResourceLocation("Resources")]

  • In Startup.cs, removed ResourcePath option from the AddLocalization middleware. (I tried with the option as well).
    Last status is; services.AddLocalization()

Do we need any other configuration in Startup.cs?

And project structure is as follows;

|--MyProject.Infrastructure
|--MyProject.Core
|--MyProject.Web
    |--Controllers
    |--ViewModels
    |--Views
       |--Customer
          |--Index.cshtml
|--MyProject.Resources
    |--Resources
       |--Controllers
       |--ViewModels
       |--Views
          |--Customer
             |--Index.en-US.resx
             |--Index.tr-TR.resx
       |--SharedResource.cs
       |--SharedResource.en-US.resx
       |--SharedResource.tr-TR.resx   

SharedResources are the only working part in project right now btw. I suspect AssemblyInfo should be placed in Web project, maybe?

@hishamco
Copy link
Contributor

SharedResources are the only working part in project right now btw. I suspect AssemblyInfo should be placed in Web project, maybe?

Nope, it should be on MyProject.Resources

@fabercs could you please share with us a minimal repo to reproduce your issue?

@fabercs
Copy link
Author

fabercs commented Nov 22, 2018

@hishamco please find the minimal repo solution linked

@hishamco
Copy link
Contributor

Sure, I will investigate on this ..

@hishamco
Copy link
Contributor

I notice there 're many thing missing such as: Suffix views with culture code Index.tr-TR.resx, AddViewLocalization() extension method .. etc.
Also there's a confusion on middleware order, please refer to Localization.StarterWeb

@fabercs
Copy link
Author

fabercs commented Nov 23, 2018

I also realized about Suffix option missing middleware and commited it. I added AddMvcLocalization() instead AddViewLocalization(), it also covers the data annotation localization, anyway I changed it to AddViewLocalization(). So after these still no effects.

@hishamco
Copy link
Contributor

Again AddLocalization() should become before AddMvc(), anyhow please make sure that your app reading the resources from within the same assembly, after that we will figure out what's the wrong with the separated assembly

@fabercs
Copy link
Author

fabercs commented Nov 23, 2018

Ok, I have deleted the solution and added a new one with the Resources folder included in web project and localization works. The class library project also included, you can play with unload/reload.

https://github.com/fabercs/Issue8739

@hishamco
Copy link
Contributor

@ryanbrandenburg how ViewLocalizer at this line https://github.com/aspnet/Mvc/blob/master/src/Microsoft.AspNetCore.Mvc.Localization/ViewLocalizer.cs#L110 will aware about the ResourceAttribute while we pass the view execution path as base name to the localizer factory?!!

@fabercs
Copy link
Author

fabercs commented Nov 26, 2018

@hishamco, as IViewLocalizerFactory is derived from IStringLocalizerFactory, it calls the same Create logic of its base. However, for view localization, because of this line

_applicationName = hostingEnvironment.ApplicationName;

you always pass the executing assembly to the factory Create logic.

https://github.com/aspnet/Localization/blob/60a3d57a3e8b8b6d69232815a9596b5a495a7d0b/src/Microsoft.Extensions.Localization/ResourceManagerStringLocalizerFactory.cs#L181

So it crates the ResourceManager based on that assembly. I have it worked by implementing my own IViewLocalizer class and overriding _applicationName for now.

@hishamco
Copy link
Contributor

There's no IViewLocalizerFactory!! the ViewLocalizer using IHtmlLocalizer which is construct from IHtmlLocalizerFactory

So it crates the ResourceManager based on that assembly. I have it worked by implementing my own IViewLocalizer class and overriding _applicationName for now.

Cool, but still I'm not sure why we need to subclass if the localizer aware about ResourceLocationAttribute, @ryanbrandenburg is there an easy way to achieve this without subclass ViewLocalizer?

@fabercs
Copy link
Author

fabercs commented Nov 26, 2018

@hishamco my mistake, I just meant to IViewLocalizerFactory, however, at the end, all make use of IStringLocalizerFactory :)

private readonly IStringLocalizerFactory _factory;

@ryanbrandenburg
Copy link
Contributor

@fabercs it's unclear to me if you're sorted now. If you're sorted we'll close this out. If your not could you re-state your current problem?

@fabercs
Copy link
Author

fabercs commented Nov 29, 2018

@ryanbrandenburg indeed I was expecting all will work properly when moving all my working (conventional) localization system from Web project to a separate project, however adding only a ResourceLocation attribute didn't do the trick. While keeping the ResourceLocation attribute, as I said above, I had to implement my own IViewLocalizer for views' localization. For data annotation localization, I had to quit namespace convention and create a shared resource which is working fine. If you say, that's what we meant to be done in our samples for localization, it is ok, you may close the issue. I have my all project localized.

@ryanbrandenburg
Copy link
Contributor

For your ViewLocalizer issue refer to this issue. It boils down to this being an abstraction issue that would force us to make assumptions about the contents of a different assembly.

For your DataAnnotations issue, could you file a new issue (now against the aspnet/AspNetCore repo since we're moving everything) so that we can keep its context clean?

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

No branches or pull requests

4 participants