如何将C#资源文件字符串转换为方法而不仅仅是属性?

pet*_*ter 13 c# resx entity-framework-core asp.net-core asp.net-core-localization

例如,EntityFramework Microsoft.EntityFrameworkCore.Relational项目在资源文件中包含以下文本:

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

生成以下C#代码:

...
/// <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;
}
...
Run Code Online (Sandbox Code Playgroud)

但是当我在VS中编辑文件并保存它时,我只生成了简单的属性,如:

...
/// <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"); }
}
...
Run Code Online (Sandbox Code Playgroud)

有问题的文件可以在这里找到:

所以问题又来了 - 他们是怎么做到的,我怎么能得到相同的结果呢?

Iva*_*oev 8

他们是如何做到的呢?

首先,显而易见的是,他们不使用标准ResXFileCodeGenerator,而是使用一些自定义代码生成工具.

目前有两种生成代码的标准方法 - 使用Custom Tool类似的旧学校方式ResXFileCodeGenerator,或使用T4模板的现代方式.所以让我们看看.

Microsoft.EntityFrameworkCore.Relational.csproj文件中的对应条目如下所示:

<ItemGroup> 
    <EmbeddedResource Include="Properties\RelationalStrings.resx">
        <LogicalName>Microsoft.EntityFrameworkCore.Relational.Properties.RelationalStrings.resources</LogicalName> 
    </EmbeddedResource> 
</ItemGroup> 
Run Code Online (Sandbox Code Playgroud)

我们可以看到,他们绝对不会使用Custom Tool.

所以它应该是一个T4模板.事实上,在上面的项目之后,我们可以看到:

<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> 
Run Code Online (Sandbox Code Playgroud)

你去吧!

现在,我不知道所包含xml文件的目的是什么而不深入实现(它可能是生成器使用的东西,如选项或其他东西),但实际的代码生成包含在以下Resources.tt中.文件.

我怎么能得到相同的结果?

我猜你要求自己的项目.好吧,你可以做类似的事情.选择您的resx文件,转到Properties并清除Custom Tool.然后添加T4 template到您的项目并编写代码生成(我不确定许可证是否允许您使用他们的代码,因此如果您想这样做,请确保首先检查是否允许).但原则是一样的.