Very late answer, but it might help someone...
I had a similar situation where I had to have the resource files in separate common assembly instead of having it inside the mail web/api project (Core 2.1). The reason being, I could be using the localized resources from other assemblies like Business or DAL layer for throwing warning/error/information messages. This is what I did:
Assume that my web project namespace is MyApp.Web
and my resources are in separate class lib MyApp.Resources
. In the resources library, create a folder (optional), say "Messages", and create a class Messages.cs
. Create the resource files inside the same folder adhering to the naming conventions. For example, Messages.fr.resx
.
In the ConfigureServices
method of the main project, add the localization without any resource path*:
services.AddLocalization();
services.Configure<RequestLocalizationOptions>(
opts =>
{
/* your configurations*/
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("en"),
new CultureInfo("fr")
};
opts.DefaultRequestCulture = new RequestCulture("en", "en");
// Formatting numbers, dates, etc.
opts.SupportedCultures = supportedCultures;
// UI strings that we have localized.
opts.SupportedUICultures = supportedCultures;
});
And in the Configure
method, add app.UseRequestLocalization();
In your controller, inject IStringLocalizer<Messages> localizer
, where Messages
is the class you created in the Resources library. All your localized resources will be available in the localizer
object, i.e., localizer["your key or default text"]
.
- The reason for not adding any
ResourcePath
in the services.AddLocalization();
options is due to the reason that both the resource files (Messages.fr.resx
) and the dummy class (Messages.cs
) are in the same path. The framework will check for the resource file relative to the class which we have specified in IStringLocalizer<>
. If the Messages.cs
was in the root folder of MyApp.Resources
lib and the resource files were inside folder "xyz", then the configuration should be services.AddLocalization(ops => ops.ResourcesPath = "xyz");
UPDATE - Responding to the queries in the comments:
MVC Views
In MVC Views, the documented approach uses IViewLocalizer
, but does not support resource sharing. So you can inject IStringLocalizer<>
in the view for using the shared resources. For example:
@inject IStringLocalizer<Messages> localizer
<h2>Information - @localizer["Shared resource access in MVC Views"]</h2>
Data Annotations
In order to use shared resources in the data annotations, you can use the factory method in the service:
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddDataAnnotationsLocalization(options => {
options.DataAnnotationLocalizerProvider = (type, factory) =>
factory.Create(typeof(Messages));
});
where the Messages
in the typeof(Messages)
is your shared resource dummy class.