ASP.NET Localization: Enabling resource expressions with an external resource assembly
- by Brian Schroer
I have several related projects that need the same localized text, so my global resources files are in a shared assembly that’s referenced by each of those projects. It took an embarrassingly long time to figure out how to have my .resx files generate “public” properties instead of “internal” so I could have a shared resources assembly (apparently it was pretty tricky pre-VS2008, and my “googling” bogged me down some out-of-date instructions). It’s easy though – Just change the “Custom Tool” to “PublicResXFileCodeGenerator”: …which can be done via the “Access Modifier” dropdown of the resource file designer window: A reference to my shared resources DLL gives me the ability to use the resources in code, but by default, the ASP.NET resource expression syntax: <asp:Button ID="BeerButton" runat="server" Text="<%$ Resources:MyResources, Beer %>" />
…assumes that your resources are in your web site project.
To make resource expressions work with my shared resources assembly, I added two classes to the resources assembly:
1) a custom IResourceProvider implementation:
1: using System;
2: using System.Web.Compilation;
3: using System.Globalization;
4:
5: namespace DuffBeer
6: {
7: public class CustomResourceProvider : IResourceProvider
8: {
9: public object GetObject(string resourceKey, CultureInfo culture)
10: {
11: return MyResources.ResourceManager.GetObject(resourceKey, culture);
12: }
13:
14: public System.Resources.IResourceReader ResourceReader
15: {
16: get { throw new NotSupportedException(); }
17: }
18: }
19: }
2) and a custom factory class inheriting from the ResourceProviderFactory base class:
1: using System;
2: using System.Web.Compilation;
3:
4: namespace DuffBeer
5: {
6: public class CustomResourceProviderFactory : ResourceProviderFactory
7: {
8: public override IResourceProvider CreateGlobalResourceProvider(string classKey)
9: {
10: return new CustomResourceProvider();
11: }
12:
13: public override IResourceProvider CreateLocalResourceProvider(string virtualPath)
14: {
15: throw new NotSupportedException(String.Format(
16: "{0} does not support local resources.",
17: this.GetType().Name));
18: }
19: }
20: }
In the “system.web / globalization” section of my web.config file, I point the “resourceProviderFactoryType" property to my custom factory:
<system.web>
<globalization culture="auto:en-US" uiCulture="auto:en-US"
resourceProviderFactoryType="DuffBeer.CustomResourceProviderFactory, DuffBeer" />
This simple approach met my needs for these projects , but if you want to create reusable resource provider and factory classes that allow you to specify the assembly in the resource expression, the instructions are here.