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:
So the question again - How did they do it, and how could I get the same result?
To convert temperatures in degrees Celsius to Fahrenheit, multiply by 1.8 (or 9/5) and add 32.
How to Convert Temperatures. First, you need the formula for converting Fahrenheit (F) to Celsius (C): C = 5/9 x (F-32)
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).
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With