Lar*_*man 5 c# asp.net msbuild localization resx
我正在努力减少大型C#/ ASP.NET解决方案的编译时间.我们的解决方案使用通常的resx文件方法翻译成大约十几种外语.解析和编译这些资源文件会大大减慢编译时间,并且每天都会受挫.
我知道可以创建自定义资源提供程序并远离.resx文件.现在,请假设我们必须坚持使用.resx文件.
通过从.csproj文件中排除除默认语言环境.resx文件之外的所有文件,我可以将编译时间缩短一半.我们的开发人员无需在日常开发过程中编译其他十几种语言.
我正在寻找防止编译外语.resx文件的方法.我想出了两种方法,我正在寻找关于一个是否优越的建议,或者是否有其他更好的方法.
我想出了两个:
更新
我编写了以下Powershell脚本,将所有外语EmbeddedResources和Compile元素移动到一个具有Conditional属性的新ItemGroup中.
$root = "C:\Code\solution_root\"
# Find all csproj files.
$projects = Get-ChildItem -Path $root -Recurse -ErrorAction SilentlyContinue -Filter *.csproj | Where-Object { $_.Extension -eq '.csproj' }
# Use a hashtable to gather a unique list of suffixes we moved for sanity checking - make sure we didn't
# relocate anything we didn't intend to. This is how I caught I was moving javascript files I didn't intend to.
$suffixes = @{}
# Find foreign resources ending in .resx and .Designer.cs
# Use a regex capture to so we can count uniques.
$pattern = "\.(?<locale>\w{2}(-\w{2,3})?\.(Designer.cs|resx))$"
foreach ($project in $projects)
{
"Processing {0}" -f $project.FullName
# Load the csproj file as XML
$xmlDoc = new-object XML
$xmlDoc.Load($project.FullName)
# Set namespace for XPath queries
$ns = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable)
$ns.AddNamespace("ns", $xmlDoc.DocumentElement.NamespaceURI)
$count = 0
$embeds = $xmlDoc.SelectNodes("//ns:EmbeddedResource",$ns)
$compiles = $xmlDoc.SelectNodes("//ns:Compile",$ns)
# Create new conditional ItemGroup node if it does not exist.
# Side-effect - every csproj will get this new element regardless of whether it
# contains foreign resources. That works for us, might not for you.
$moveToNode = $xmlDoc.SelectSingleNode("//ns:ItemGroup[@Condition=`" '`$(Configuration)'=='Release' `"]", $ns)
if ($moveToNode -eq $null) {
# When creating new elements, pass in the NamespaceURI from the parent node.
# If we don't do this, elements will get a blank namespace like xmlns="", and this will break compilation.
# Hat tip to https://stackoverflow.com/questions/135000/how-to-prevent-blank-xmlns-attributes-in-output-from-nets-xmldocument
$conditionAtt = $xmlDoc.CreateAttribute("Condition")
$conditionAtt.Value = " '`$(Configuration)'=='Release' "
$moveToNode = $xmlDoc.CreateElement("ItemGroup", $xmlDoc.Project.NamespaceURI)
$ignore = $moveToNode.Attributes.Append($conditionAtt)
$ignore = $xmlDoc.LastChild.AppendChild($moveToNode)
}
# Loop over the EmbeddedResource and Compile elements.
foreach ($resource in ($embeds += $compiles)) {
# Exclude javascript files which I found in our Web project.
# These look like *.js.resx or *.js.Designer.cs and were getting picked up by my regex.
# Yeah, I could make a better regex, but I'd like to see my kids today.
if ($resource.Include -notmatch "js\.(Designer.cs|resx)$" -and $resource.Include -match $pattern ) {
# We have a foreign-language resource.
# Track unique suffixes for reporting later.
$suffix = $matches['locale']
if (!$suffixes.ContainsKey($suffix)) {
$ignore = $suffixes.Add($suffix,"")
}
$ignore = $moveToNode.InsertBefore($resource, $null)
# Count how many we moved per project.
$count += 1
}
}
"Moved {0} resources in {1}.`n" -f $count, $project.Name
$xmlDoc.Save($project.FullName)
}
echo "The following unique suffixes were processed."
$suffixes.Keys | sort
Run Code Online (Sandbox Code Playgroud)
您可以利用 MSBuild 中的现有机制来处理这种情况,例如此处记录的<Choose>
元素以及引入您自己的构建配置的选项。如果您的开发人员在日常工作中仅构建调试配置,您甚至可能不需要自己的构建配置:您可以设置您的项目,以便所有外语资源仅包含在发布版本中。
此项目文件部分将确保波兰语资源仅在发布配置中构建(语言代码可能是错误的,但您明白了):
<Choose>
<When Condition=" '$(Configuration)'=='Release' ">
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.pl.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.pl.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.pl.Designer.cs">
<DependentUpon>Resources.pl.resx</DependentUpon>
<AutoGen>True</AutoGen>
</Compile>
<!-- TODO: add other language resources as necessary-->
</ItemGroup>
</When>
</Choose>
Run Code Online (Sandbox Code Playgroud)
如果您的开发人员需要构建发布配置,您可以创建自己的配置 ReleaseResx 并仅在该配置中包含外语 .resx 文件。
您的建议也都有效,我只是认为这种方法更干净。
归档时间: |
|
查看次数: |
972 次 |
最近记录: |