-
Notifications
You must be signed in to change notification settings - Fork 6k
MSBuild Resource Naming Convention Breaking Change #16964
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Shouldn't this be well documented/clearly indicated in official globalization docs? Specifically in the Using one resource string for multiple classes part where if performing this as recommended, it won't work at all (that is simply creating a class named |
@os1r1s110 or @benvillalobos Can you elaborate on why the shared resources won't work given this change? I'm happy to update the docs with this info. Is the fix to enable the shared resources to work to set EmbeddedResourceUseDependentUponConvention to false in the project file? |
@gewarren I did set this line And then, this works:
This does not work:
The latter scenario will work though, if you remove the ResourcesPath. This should be clearly stated on the documentation as it is very confusing at the moment. |
Here's a fun one I ran into today: I have a test project that includes seed data in scripts (one script per table):
The build was completely ignoring this file: Renaming the file to |
@benvillalobos , 3 worked if I remove the .cs extension for
|
@Ponant Does this happen prior to net6? |
@benvillalobos , I can't tell you, I switched from .Net Core 2.1 to .Net 6 as I worked on other frameworks. This issue is found on a new template from visual studio 2022, Version 17.0.0 Preview 3.1, if that helps.
|
@Ponant Thanks for bringing this to my attention! Could you file a feedback ticket on the Developer Community site and include binary logs or a minimal project that reproduces the issue with the ticket? Please link the issue here so I can expedite routing it to our team. |
@benvillalobos , I would gladly do so but I cannot at the moment because I have a very poor internet connection which makes it already hard to only reply in this comment! I could try without the binary logs as these might be heavy, otherwise you will have to wait for September 5 as I will be back with a good internet connection. Let me know. I am not sure I could upload a project on my github repo either, but I can try. Anyways, the project is a very brand new template with the localization middleware enabled. |
@benvillalobos , it fails also for .Net 5. |
@benvillalobos , also fails with .Net Core 3.1. |
Uh oh!
There was an error while loading. Please reload this page.
Resource Naming Conventions Have Changed
For those that would like a slightly higher level explanation and maybe even a mediocre diagram of what's going on here, see this gist I created.
Version introduced
3.0, via applying DependentUpon convention, but more specifically applying that convention to localized resources. Here is the related MSBuild issue that tracked this.
Old behavior
When the
DependentUpon
metadata was set, the manifest name would beFullTypeName.resources
where FullTypeName isNamespace.Classname
. When theDependentUpon
metadata was NOT set, the manifest names default to:FullTypeName.FolderPathRelativeToRoot.Culture.resources
.New behavior
When a resx is associated with a type like in the winforms case, the generally presumed convention is that the resource is called
FullTypeName.resources
(the culture may or may not be present,FullTypeName.Culture.resources
for example).From this presumed convention, the rules around how RootNamespace and folders impact the name chosen mirror how VS picks a namespace and name for a new class:
RootNamespace.FoldersSeparatedByDots.FileName.(resx|resources|cs)
So if you leave all the defaults when you add files and resources in VS, then when you have Type.cs next to Type.resx, you will get FullNameOfType.resources. However, when you stray from the defaults, there’s more to it.
The points below are the rules with which manifest resource names are generated:
1. If the metadata LogicalName
%(EmbeddedResource.LogicalName)
is set, then use it as is.Examples:
Then the resource is
SomeName.resources
, irrespective of the.resx
file name, culture, or any other metadata.2. else if the metadata ManifestResourceName
%(EmbeddedResource.ManifestResourceName)
is set then add the.resources
extension and use it.Examples:
Then the resource name is SomeName.resources
Then the resource name is SomeName.fr-FR.resources
3. else if
%(EmbeddedResource.DependentUpon)
is set to a source file, then parse the source file and add culture and.resources
extension to the full type name of the first class in the file. This allows types to be renamed and have the corresponding resource change names accordingly.Given Q.cs:
Examples:
Then the resource name is
SomeNamespace.SomeType.resources
Then the resource name is
SomeNamespace.SomeType.fr-FR.resources
4. else if
EmbeddedResourceUseDependentUponConvention
is set totrue
(which is true by default for projects targeting .net core 3+), then choose DependentUpon as follows and perform rule 3 above.If there is a source file in the same folder that has the same name as the resx when not including culture or file extensions, choose DependentUpon from the resx to the source file.
Example:
Src/
Q.cs: namespace SomeNamespace { class SomeType {} }}
Q.resx --> resource name is
SomeNamespace.SomeType.resources
Q.fr-Fr.resx --> resource name is
SomeNamespace.SomeType.fr-FR.resources
5. else let RelativePath = %(EmbeddedResource.Link) if set, else %(EmbeddedResource.Identity). (This is the path in solution explorer from project root to file.) Then use $(RootNamespace).(RelativePathWithDotsForSlashes).Culture?.resources
Reason for change
We had various issues(1, 2, 3) revolving around the desire to get users to migrate to .NET Core and how MSBuild handles embedded resources being a blocker for that.
Recommended action
If you're unsatisfied with the manifest names that are currently being generated, simply add this line to your project file:
Setting this tag to false is how you opt out of this convention entirely. Do note that rules 1 and 2 above still apply.
Otherwise, modify your resource file metadata to satisfy one of the above rules.
Category
Issue metadata
The text was updated successfully, but these errors were encountered: