Skip to content

Commit c958451

Browse files
authored
feat(namespace): update RootNamespace and AssemblyName in project file (#16)
1 parent b9acac9 commit c958451

File tree

3 files changed

+86
-3
lines changed

3 files changed

+86
-3
lines changed

src/CodingWithCalvin.ProjectRenamifier/CodingWithCalvin.ProjectRenamifier.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
<DependentUpon>RenameProjectDialog.xaml</DependentUpon>
7171
</Compile>
7272
<Compile Include="ProjectRenamifierPackage.cs" />
73+
<Compile Include="Services\ProjectFileService.cs" />
7374
<Compile Include="source.extension.cs">
7475
<AutoGen>True</AutoGen>
7576
<DesignTime>True</DesignTime>
@@ -109,6 +110,7 @@
109110
<Reference Include="System" />
110111
<Reference Include="System.Design" />
111112
<Reference Include="System.ComponentModel.Composition" />
113+
<Reference Include="System.Xml" />
112114
<Reference Include="System.Xaml" />
113115
<Reference Include="PresentationCore" />
114116
<Reference Include="PresentationFramework" />

src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.IO;
33
using System.Windows.Interop;
44
using CodingWithCalvin.ProjectRenamifier.Dialogs;
5+
using CodingWithCalvin.ProjectRenamifier.Services;
56
using EnvDTE;
67
using EnvDTE80;
78

@@ -78,11 +79,13 @@ private void RenameProject(Project project, DTE2 dte)
7879
}
7980

8081
var newName = dialog.NewProjectName;
82+
var projectFilePath = project.FullName;
8183

82-
// TODO: Implement the actual rename operation
84+
// Update RootNamespace and AssemblyName in .csproj
85+
ProjectFileService.UpdateProjectFile(projectFilePath, currentName, newName);
86+
87+
// TODO: Implement remaining rename operations
8388
// See open issues for requirements:
84-
// - #6: Update RootNamespace in .csproj
85-
// - #7: Update AssemblyName in .csproj
8689
// - #8: Update namespace declarations in source files
8790
// - #9: Update using statements across solution
8891
// - #11: Solution folder support
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using System.Xml;
2+
3+
namespace CodingWithCalvin.ProjectRenamifier.Services
4+
{
5+
/// <summary>
6+
/// Service for updating project file (.csproj) elements.
7+
/// </summary>
8+
internal static class ProjectFileService
9+
{
10+
/// <summary>
11+
/// Updates the RootNamespace and AssemblyName elements in a project file
12+
/// if they match the old project name.
13+
/// </summary>
14+
/// <param name="projectFilePath">Full path to the .csproj file.</param>
15+
/// <param name="oldName">The old project name to match against.</param>
16+
/// <param name="newName">The new project name to set.</param>
17+
/// <returns>True if any changes were made, false otherwise.</returns>
18+
public static bool UpdateProjectFile(string projectFilePath, string oldName, string newName)
19+
{
20+
var doc = new XmlDocument();
21+
doc.PreserveWhitespace = true;
22+
doc.Load(projectFilePath);
23+
24+
var modified = false;
25+
26+
modified |= UpdateElement(doc, "RootNamespace", oldName, newName);
27+
modified |= UpdateElement(doc, "AssemblyName", oldName, newName);
28+
29+
if (modified)
30+
{
31+
doc.Save(projectFilePath);
32+
}
33+
34+
return modified;
35+
}
36+
37+
/// <summary>
38+
/// Updates a specific element in the project file if its value matches the old name.
39+
/// </summary>
40+
private static bool UpdateElement(XmlDocument doc, string elementName, string oldName, string newName)
41+
{
42+
// Handle both SDK-style (no namespace) and legacy (with namespace) project files
43+
var namespaceManager = new XmlNamespaceManager(doc.NameTable);
44+
var msbuildNs = "http://schemas.microsoft.com/developer/msbuild/2003";
45+
46+
// Check if document uses the MSBuild namespace
47+
var hasNamespace = doc.DocumentElement?.NamespaceURI == msbuildNs;
48+
49+
XmlNodeList nodes;
50+
if (hasNamespace)
51+
{
52+
namespaceManager.AddNamespace("ms", msbuildNs);
53+
nodes = doc.SelectNodes($"//ms:{elementName}", namespaceManager);
54+
}
55+
else
56+
{
57+
nodes = doc.SelectNodes($"//{elementName}");
58+
}
59+
60+
if (nodes == null || nodes.Count == 0)
61+
{
62+
return false;
63+
}
64+
65+
var modified = false;
66+
foreach (XmlNode node in nodes)
67+
{
68+
if (node.InnerText.Equals(oldName, StringComparison.OrdinalIgnoreCase))
69+
{
70+
node.InnerText = newName;
71+
modified = true;
72+
}
73+
}
74+
75+
return modified;
76+
}
77+
}
78+
}

0 commit comments

Comments
 (0)