Can we skip the ResourceManager?

I am working on a project where I use ResourceManager extensively, and this question just crossed my mind. Can we read .resx files without using the ResourceManager? I mean, is there any other way?

+6
source share
4 answers

ResourceManager is a convenience class, it works great with the way the build system supports .resx files. No, this is not a strict necessity.

The .NET compilation has the general ability to embed arbitrary data in the assembly manifest. Just a drop of bytes, that could be all you want. Directly supported by the build system, just add the file to your project and set its build action to "Built-in resource." At run time, you retrieve data in this file using Assembly.GetManifestResourceStream () .

You can stop right there, but this is just one file, it does not scale very well if you have many small resources that you want to implement. Where the .resx file starts, it is an XML file containing resources in a friendly format. One that gives you a chance to fight again when the original is lost.

But the XML format is not a good format for resource data, it is cumbersome and expensive to find data back. So, .NET has resgen.exe, a build tool that turns an XML file into a binary file, a .resources file. Compact and easy to use. And suitable for direct embedding into a separate manifest resource.

What you do not want to do is read the .resources data yourself. You will want to use a helper class that can find certain resources from byte bytes. You want to use the ResourceReader class , its GetResourceData() allows you to specify the name of the resource, and it will spit out the resource type and data back.

You can stop right there, but the application often needs different sets of resources. A very general need for localization. This is what satellite assemblies are, different assemblies that contain nothing but resources for each particular culture. They are separated from each other, so you do not pay for the virtual memory needed to store all localized resources when you need only one set of them. Here you need a helper class that automatically finds and loads the correct satellite assembly and retrieves the resource for you based on the current culture.

This helper class is ResourceManager .

+16
source

If you decide to skip using the ResourceManager , you can let Visual Studio handle the code generation for you. Ultimately, the generated code uses the ResourceManager , but you no longer write this code manually. In addition, you get a compile-time check, since you are referring to a generated static class.

If you add a resource file to your project and double-click it in Solution Explorer, Visual Studio will present you with a dialog where you can enter the name of the resource and its value. The dialog box provides options for adding resources in the form of strings, images, audio, etc. (See the dropdown menus at the top of the dialog box). Then, to get the code generation bit, you need to set the Access Modifier both "Public" and "Internal". Third option: "No code generation."

For example, add a resource file called "MyResources", then add a string resource named Greeting and value Hello! . One of the two previous options chosen to generate the code (start by testing it, restrict access as needed), now you can link to resources from your code through MyResources.Greeting . If you donโ€™t see it right away, make sure you save the file and try compiling.

 string greeting = MyResources.Greeting; // "Hello!" 

If you add other types of resources (image, audio, etc.), then the return types will be different, of course.

At this point, you can check the generated .cs file and see that the generated code uses the ResourceManager . Another use of resource files is localization. Let's say you need the Spanish version of MyResources . You would add a new file called MyResources.es.resx , where es matches the desired language code (in this case, Spanish). Now add the Greeting resource name with the Spanish value Hola! .

If you change the stream culture to Spanish, a link to the resource will return the Spanish version:

 string defaultGreeting = MyResources.Greeting; // "Hello!" Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("es"); string spanishGreeting = MyResources.Greeting; // "Hola!" 

Note that you really need to set an access modifier for one of the code generation options for your default resource file (i.e. MyResources.resx ), and not for all other localized versions that you add. There is no harm in this, but, in my opinion, it is cleaner to have a main file created, while others just have the required resource values โ€‹โ€‹without generating code.

+6
source

Well, resources are assembled. You can try to read the assembly by reading bytes (or IL) and extract resources from there.

The ResourceManager does it all for you, so I couldnโ€™t think of any reason why you want to do this ... Maybe if you do not want to load the assembly into memory, you can do it without the ResourceManager.

+2
source

Microsoft Ref: Introduces a resource manager that provides convenient access to culture-dependent resources at runtime.

I expect that you would use multi Lang, you will get a more consistent result and better compatibility.

IMHO

+1
source

All Articles