开发者

How to do inheritance of Resource files (resx)

Imagine you're working on a .Net 4.0 project that is made up of hundreds of assemblies, each having its own resource file (.resx) for localization. The localized strings are accessed from C# through classes auto-generated with ResXFileCodeGenerator (which creates a "ResourceFile.Designer.cs" file): string test = ResourceFile.TestString;

Each assembly has localized strings which are particular to it, but there are strings which are common to all assemblies. You tell yourself that it would be nice to have those "common strings" in a "parent" resource开发者_Go百科 file, on which the code would fall back if the resource key is not available in the "local" resource file. You then say "Hey! inheritance could work here." And indeed, doing something like this in the auto-generated designer file does work: internal class ResourceFile : ParentResourceFile That is, strings not defined in ResourceFile, but defined in ParentResourceFile, can still be accessed with ResourceFile.StringInParentFile.

But something in the designer file's header troubles you: "Changes to this file may cause incorrect behavior and will be lost if the code is regenerated." Plus you know playing in the auto-generated designer files is frowned upon. So you come here, and you ask:

  • When does ResXFileCodeGenerator generate/regenerate the designer class?
  • Is there a way to turn off that auto-generation?
  • Will we have to forego the advantages of ResXFileCodeGenerator and implement our own handling of ResourceManager?

And you say "thank you".


After investigating the issue for a while, I've settled for a workaround: do inheritance not on the resource files themselves, but on the classes that need to access the "parent" resources.

You only need to have a base class whose project includes a "master" resource file, and set that resource file's CustomTool property to PublicResXFileCodeGenerator (the "Public" part is important as it will create a public class, as opposed to an internal one). One restriction is that PublicResXFileCodeGenerator is only available starting with VS2008 (this CodeProject article could otherwise be helpful).

Then, in classes which need to access the "master" resources, simply inherit from the base class and access the resources like this:

public class ChildClass : BaseClass
{
    string test = BaseClass.BaseResourceFile.TestString; // a common resource
    string localResource = ResourceFile.OtherString;     // a local resource
}

One disadvantage with this solution is that you have to explicitly reference the BaseResourceFile to access resources defined there; there's no fallback to the parent class like there would be if inheritance was done directly between the Resource classes.

And for posterity, I'll answer my own questions:

  • When does ResXFileCodeGenerator generate/regenerate the designer class?

    Whenever a resource is added/removed/modified.

  • Is there a way to turn off that auto-generation?

    No. And anyway, a "code generator" tool without auto-generation would be pretty useless, don't you think?

  • Will we have to forego the advantages of ResXFileCodeGenerator and implement our own handling of ResourceManager?

    No, see above answer.

We also considered implementing a solution using "linked" files (from the "Add existing item" dialog, using the "Add as link" option) where one parent resource file would be linked to all our assemblies, but since our assemblies already inherit from a base class, it seemed much better to go the inheritance way.

I don't really feel comfortable accepting my own answer, so if anyone comes up with a better solution or improvements on my solution, I'd gladly accept that. That is, if anyone cares at all.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜