Skip to content

Commit b0b1f6f

Browse files
authored
Update manifest breaking change (#18306)
* update manifest breaking change
1 parent b340903 commit b0b1f6f

File tree

5 files changed

+27
-59
lines changed

5 files changed

+27
-59
lines changed

docs/core/compatibility/2.2-3.0.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ If you're migrating from version 2.2 to version 3.0 of .NET Core, ASP.NET Core,
375375

376376
## MSBuild
377377

378-
- [Resource manifest file name change](#resource-manifest-file-names)
378+
- [Resource manifest file name change](#resource-manifest-file-name-change)
379379

380380
[!INCLUDE[Resource file names](~/includes/core-changes/msbuild/3.0/resource-manifest-name.md)]
381381

docs/core/compatibility/2.2-3.1.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ If you're migrating from version 2.2 to version 3.1 of .NET Core, ASP.NET Core,
378378

379379
## MSBuild
380380

381-
- [Resource manifest file name change](#resource-manifest-file-names)
381+
- [Resource manifest file name change](#resource-manifest-file-name-change)
382382

383383
[!INCLUDE[Resource file names](~/includes/core-changes/msbuild/3.0/resource-manifest-name.md)]
384384

docs/core/compatibility/fx-core.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ If you're migrating an app from .NET Framework to .NET Core, the breaking change
4848

4949
***
5050

51+
## MSBuild
52+
53+
- [Resource manifest file name change](#resource-manifest-file-name-change)
54+
55+
### .NET Core 3.0
56+
57+
[!INCLUDE[Resource file names](~/includes/core-changes/msbuild/3.0/resource-manifest-name.md)]
58+
59+
***
60+
5161
## Networking
5262

5363
- [WebClient.CancelAsync doesn't always cancel immediately](#webclientcancelasync-doesnt-always-cancel-immediately)

docs/core/compatibility/msbuild.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ ms.date: 02/10/2020
77

88
The following breaking changes are documented on this page:
99

10-
- [Resource manifest file name change](#resource-manifest-file-names)
10+
- [Resource manifest file name change](#resource-manifest-file-name-change)
1111

1212
## .NET Core 3.0
1313

includes/core-changes/msbuild/3.0/resource-manifest-name.md

Lines changed: 14 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,36 @@
1-
### Resource manifest file names
1+
### Resource manifest file name change
22

3-
Starting in .NET Core 3.0, the generated resource manifest file name has changed.
3+
Starting in .NET Core 3.0, in the default case, MSBuild generates a different manifest file name for resource files.
44

55
#### Version introduced
66

77
3.0
88

99
#### Change description
1010

11-
Prior to .NET Core 3.0, when [DependentUpon](/visualstudio/msbuild/common-msbuild-project-items#compile) metadata was set for a resource (*.resx*) file in the MSBuild project file, the generated manifest name was *Namespace.Classname.resources*. When [DependentUpon](/visualstudio/msbuild/common-msbuild-project-items#compile) was not set, the generated manifest name was *Namespace.Classname.FolderPathRelativeToRoot.Culture.resources*.
11+
Prior to .NET Core 3.0, if no `LogicalName`, `ManifestResourceName`, or `DependentUpon` metadata was specified for an `EmbeddedResource` item in the project file, MSBuild generated a manifest file name in the pattern `<RootNamespace>.<ResourceFilePathFromProjectRoot>.resources`. If `RootNamespace` is not defined in the project file, it defaults to the project name. For example, the generated manifest name for a resource file named *Form1.resx* in the root project directory was *MyProject.Form1.resources*.
1212

13-
Starting in .NET Core 3.0, when a *.resx* file is colocated with a source file of the same name, for example, in Windows Forms apps, the resource manifest name is generated from the full name of the first type in the source file. For example, if *Type.cs* is colocated with *Type.resx*, the generated manifest name is *Namespace.Classname.resources*. However, if you modify any of the attributes on the `EmbeddedResource` property for the *.resx* file, the generated manifest file name may be different:
13+
Starting in .NET Core 3.0, if a resource file is colocated with a source file of the same name (for example, *Form1.resx* and *Form1.cs*), MSBuild uses type information from the source file to generate the manifest file name in the pattern `<Namespace>.<ClassName>.resources`. The namespace and class name are extracted from the first type in the colocated source file. For example, the generated manifest name for a resource file named *Form1.resx* that's colocated with a source file named *Form1.cs* is *MyNamespace.Form1.resources*. The key thing to note is that the first part of the file name is different to prior versions of .NET Core (*MyNamespace* instead of *MyProject*).
1414

15-
- If the `LogicalName` attribute on the `EmbeddedResource` property is set, that value is used as the resource manifest file name.
15+
> [!NOTE]
16+
> If you have `LogicalName`, `ManifestResourceName`, or `DependentUpon` metadata specified on an `EmbeddedResource` item in the project file, then this change does not affect that resource file.
1617
17-
Examples:
18+
This breaking change was introduced with the addition of the `EmbeddedResourceUseDependentUponConvention` property to .NET Core projects. By default, resource files aren't explicitly listed in a .NET Core project file, so they have no `DependentUpon` metadata to specify how to name the generated *.resources* file. When `EmbeddedResourceUseDependentUponConvention` is set to `true`, which is the default, MSBuild looks for a colocated source file and extracts a namespace and class name from that file. If you set `EmbeddedResourceUseDependentUponConvention` to `false`, MSBuild generates the manifest name according to the previous behavior, which combines `RootNamespace` and the relative file path.
1819

19-
```xml
20-
<EmbeddedResource Include="X.resx" LogicalName="SomeName.resources" />
21-
-or-
22-
<EmbeddedResource Include="X.fr-FR.resx" LogicalName="SomeName.resources" />
23-
```
24-
25-
**Generated resource manifest file name**: *SomeName.resources* (regardless of the *.resx* file name or culture or any other metadata).
26-
27-
- If `LogicalName` is not set, but the `ManifestResourceName` attribute on the `EmbeddedResource` property is set, its value, combined with the file extension *.resources*, is used as the resource manifest file name.
28-
29-
Examples:
30-
31-
```xml
32-
<EmbeddedResource Include="X.resx" ManifestResourceName="SomeName" />
33-
-or-
34-
<EmbeddedResource Include="X.fr-FR.resx" ManifestResourceName="SomeName.fr-FR" />
35-
```
20+
#### Recommended action
3621

37-
**Generated resource manifest file name**: *SomeName.resources* or *SomeName.fr-FR.resources*.
22+
In most cases, no action is required on the part of the developer, and your app should continue to work. However, if this change breaks your app, you can either:
3823

39-
- If the previous rules don't apply, and the `DependentUpon` attribute on the `EmbeddedResource` element is set to a source file, the type name of the first class in the source file is used in the resource manifest file name. More specifically, the generated file name is *Namespace.Classname\[.Culture].resources*.
24+
- Change your code to expect the new manifest name.
4025

41-
Examples:
26+
- Opt out of the new naming convention by setting `EmbeddedResourceUseDependentUponConvention` to `false` in your project file.
4227

4328
```xml
44-
<EmbeddedResource Include="X.resx" DependentUpon="MyTypes.cs">
45-
-or-
46-
<EmbeddedResource Include="X.fr-FR.resx" DependentUpon="MyTypes.cs">
29+
<PropertyGroup>
30+
<EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention>
31+
</PropertyGroup>
4732
```
4833

49-
**Generated resource manifest file name**: *Namespace.Classname.resources* or *Namespace.Classname.fr-FR.resources* (where `Namespace.Classname` is the name of the first class in *MyTypes.cs*).
50-
51-
- If the previous rules don't apply, `EmbeddedResourceUseDependentUponConvention` is `true` (the default for .NET Core), and there's a source file colocated with a *.resx* file that has the same base file name, the *.resx* file is made dependent upon the matching source file, and the generated name is the same as in the previous rule. This is the "default settings" rule for .NET Core projects.
52-
53-
Examples:
54-
55-
Files *MyTypes.cs* and *MyTypes.resx* or *MyTypes.fr-FR.resx* exist in the same folder.
56-
57-
**Generated resource manifest file name**: *Namespace.Classname.resources* or *Namespace.Classname.fr-FR.resources* (where `Namespace.Classname` is the name of the first class in *MyTypes.cs*).
58-
59-
- If none of the previous rules apply, the generated resource manifest file name is *RootNamespace.RelativePathWithDotsForSlashes.\[Culture.]resources*. The relative path is the value of the `Link` attribute of the `EmbeddedResource` element if it's set. Otherwise, the relative path is the value of the `Identity` attribute of the `EmbeddedResource` element. In Visual Studio, this is the path from the project root to the file in Solution Explorer.
60-
61-
#### Recommended action
62-
63-
If you're unsatisfied with the generated manifest names, you can:
64-
65-
- Modify your resource file metadata according to one of the previously described naming rules.
66-
67-
- Set `EmbeddedResourceUseDependentUponConvention` to `false` in your project file to opt out of the new convention entirely:
68-
69-
```xml
70-
<EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention>
71-
```
72-
73-
> [!NOTE]
74-
> If the `LogicalName` or `ManifestResourceName` attributes are present, their values will still be used for the generated file name.
75-
7634
#### Category
7735

7836
MSBuild

0 commit comments

Comments
 (0)