Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert C# Resource File Strings into methods and not just properties?

Example, the EntityFramework Microsoft.EntityFrameworkCore.Relational project has the following text in the resource files:

...
<data name="FromSqlMissingColumn" xml:space="preserve">
  <value>The required column '{column}' was not present in the results of a 'FromSql' operation.</value>
</data>
...

which generates the following C# code:

...
/// <summary>
/// The required column '{column}' was not present in the results of a 'FromSql' operation.
/// </summary>
public static string FromSqlMissingColumn([CanBeNull] object column)
{
    return string.Format(CultureInfo.CurrentCulture, GetString("FromSqlMissingColumn", "column"), column);
}
...
private static string GetString(string name, params string[] formatterNames)
{
    var value = _resourceManager.GetString(name);

    Debug.Assert(value != null);

    if (formatterNames != null)
    {
        for (var i = 0; i < formatterNames.Length; i++)
        {
            value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
        }
    }

    return value;
}
...

But when I edit the file in VS and save it, I get only simple properties generated, like:

...
/// <summary>
/// The required column '{column}' was not present in the results of a 'FromSql' operation.
/// </summary>
public static string FromSqlMissingColumn
{
    get { return ResourceManager.GetString("FromSqlMissingColumn"); }
}
...

The files in question can be found here:

  • RelationalStrings.resx
  • RelationalStrings.Designer.cs

So the question again - How did they do it, and how could I get the same result?

like image 479
peter Avatar asked Jul 21 '16 17:07

peter


People also ask

How do you convert Celsius to Fahrenheit easy?

To convert temperatures in degrees Celsius to Fahrenheit, multiply by 1.8 (or 9/5) and add 32.

What is the formula to C?

How to Convert Temperatures. First, you need the formula for converting Fahrenheit (F) to Celsius (C): C = 5/9 x (F-32)

How do you convert Celsius to Fahrenheit example?

For example, let us convert 20° Celsius to Fahrenheit: °F = 20 × (9/5) + 32 = 36 + 32 = 68°F. Therefore, 20° Celsius is equal to 68° Fahrenheit (20°C = 68°F).

How do you convert Fahrenheit to Celsius?

To convert Fahrenheit to celsius, the formula used is °C = 5/9(°F – 32). Using Fahrenheit to Celsius formula (F to C formula), the temperature in Fahrenheit can easily be converted into Celsius. Example: Convert 80 Fahrenheit to Celsius.


1 Answers

How did they do it?

First it should be obvious that they don't use the standard ResXFileCodeGenerator, but some custom code generation tool.

Currently there are 2 standard ways of generating code - the old school way using a Custom Tool similar to ResXFileCodeGenerator, or the modern way using a T4 Template. So let see.

The correspondig entry inside the Microsoft.EntityFrameworkCore.Relational.csproj file looks like this:

<ItemGroup> 
    <EmbeddedResource Include="Properties\RelationalStrings.resx">
        <LogicalName>Microsoft.EntityFrameworkCore.Relational.Properties.RelationalStrings.resources</LogicalName> 
    </EmbeddedResource> 
</ItemGroup> 

As we can see, definitely they do not use Custom Tool.

So it should be a T4 template. And indeed right after the above item we can see:

<ItemGroup> 
    <Content Include="..\..\tools\Resources.tt"> 
        <Link>Properties\Resources.tt</Link> 
            <Generator>TextTemplatingFileGenerator</Generator> 
            <LastGenOutput>Resources.cs</LastGenOutput> 
            <CustomToolNamespace>Microsoft.EntityFrameworkCore.Internal</CustomToolNamespace> 
    </Content> 
    <Content Include="Properties\Microsoft.EntityFrameworkCore.Relational.rd.xml" /> 
</ItemGroup> 

So there you go!

Now, I don't know what's the purpose of the included xml file without diving into the implementation (it might be something that is used by the generator, like options or something), but the actual code generation is contained in the following Resources.tt file.

how could I get the same result?

I guess you are asking for your own projects. Well, you can do something similar. Select your resx file, go to Properties and clear the Custom Tool. Then add T4 template to your project and write the code generation (I'm not sure if the license allows you to use their code, so if you want to do so, make sure you first check if it is allowed). But the principle would be the same.

like image 82
Ivan Stoev Avatar answered Sep 24 '22 19:09

Ivan Stoev