Skip to content

Add support for compiling resx files to embedded resources - #548

Open
soda0289 wants to merge 2 commits into
bazel-contrib:masterfrom
soda0289:users/reyad/add-resx-file-compilation
Open

Add support for compiling resx files to embedded resources#548
soda0289 wants to merge 2 commits into
bazel-contrib:masterfrom
soda0289:users/reyad/add-resx-file-compilation

Conversation

@soda0289

@soda0289 soda0289 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

This PR adds support for compiling .resx files that contain basic string data into resource files. It does this by using a new tool resourcegen that compiles .resx files using dotnet ResourceWriter. This tool is called from a new rule resx_resource that can take in .resx files as well as culture variants or translations of these files Strings.fr.resx to support localization. Localization support has been brought up before in issue #466 and it would allow for existing dotnet projects to migrate to bazel without using extra tooling or moving away from resx.

Here is an example that I added to the README.md in docs:

load("@rules_dotnet//dotnet:defs.bzl", "csharp_library", "resx_resource")

resx_resource(
    name = "strings",
    srcs = [
        "Strings.resx",      # neutral / culture-invariant
        "Strings.fr.resx",   # French
        "Strings.de.resx",   # German
    ],
)

csharp_library(
    name = "greeter",
    srcs = ["Greeter.cs"],
    out = "Localization",
    resx = [":strings"],
    target_frameworks = ["net9.0"],
)

That would then create resources, one for the neutral Strings.resx that is built into the dll/exe and one for each language as a dll that is shipped alongside the dll/exe. It can be read using dotnet ResourceManager

namespace Localization
{
    public static class Greeter
    {
        private static readonly ResourceManager Rm =
            new ResourceManager("Localization.Strings", typeof(Greeter).Assembly);

        // Culture would be "fr" or "de" or "" for neutral.
        public static string Hello(string culture) =>
            Rm.GetString("Hello", CultureInfo.GetCultureInfo(culture)) ?? "<missing>";
    }
}

This is the same thing as MSBuild csproj file EmbeddedResource item. MSBuild will automatically compile resx files and the culture variants into resources or satellite assemblies in the same way as this change does using the resx_resource rule.

<ItemGroup>
  <EmbeddedResource Include="Resources\Strings.resx" />
  <EmbeddedResource Include="Resources\Strings.fr.resx" />
  <EmbeddedResource Include="Resources\Strings.de.resx" />
</ItemGroup>

It also adds support for LogicalName attribute that can be used to rename <EmbeddedResource> instead of using the file name of the resx file. This is done using logical_names attribute in the resx_resource rule. Only the neutral resx file needs to be mapped.

In the future this could be expanded to handle more types of resx files that include binary data but I think starting with just string data for localization is the most common use case.

@soda0289
soda0289 requested a review from purkhusid as a code owner July 13, 2026 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant