In our application there are 1000's of uses of the static properties in the Resources.designer.cs
files. For example:
Resources.string_to_identify_the_resource
We also have our own class which looks up resources but also allows resources to be overridden from other assemblies. This is useful if we have a customer that wants to rename a plugin or products, as we simply have to drop in a dll and its done. This class is used like:
Resources.GetString("string_to_identify_the.resource");
We want all our resources to be looked up through our own Resources class so they can be overridden and I have been tasked with doing this. I do not fancy going through and re-factoring all the code.
My initial idea was to use a custom DynamicObject:
public class Resources
{
public static dynamic Dynamic = new StaticResourcesDynamicObject();
class StaticResourcesDynamicObject : DynamicObject
{
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = GetString(binder.Name);
return true;
}
}
// Existing code to lookup resources
public static string GetString(string name)
{
...
}
}
So
Resources.string_to_identify_the_resource
would be simply be renamed to:
Resources.Dynamic.string_to_identify_the_resource
The main problem is that a lot of the resource names contain periods (.
) so they do not match the static properties. For example Cmd.Too_Much
has a static property of Cmd_Too_Much
.
I could just attempt to fetch all the different possibilities or does anybody else have a solution to the problem?
In order to do this you have to create a custom code generator because Visual Studio generates the resources for you. The classes that get generated are static, not extensible and very tightly coupled to the .NET ResourceManager that works with Resx.
You can change this by creating a custom strongly typed resource generator and replace that in visual studio. Visual Studio uses
ResXFileCodeGenerator
andPublicResXFileCodeGenerator
, or you can create a standalone tool that runs through all the Resx files in a project and generates custom strongly typed resource classes.If you want to get an idea how you might do this you can look at Westwind.Globalization which includes a
StronglyTypedResources
class that does just that for creating strongly typed classes for database resources (or Resx). You can take that code and modify it to generate custom classes that do what you need.That said I think dynamic is not what you want here. Rather can create the Getters in such a way that they implement the logic you want to execute. For example, I like to ensure that if a resource is not found, something is always returned - never a null or blank value. So if a resource is missing I return the resource Id which is better than nothing.