RefactorMCP catalog

Sync Namespace with Folder

Sets the namespace of a file to the one its location implies: the project's root namespace followed by the folders between the project and the file. Billing/Taxes/Rate.cs in a project whose root namespace is Shop gets the namespace Shop.Billing.Taxes.

Arguments

ArgumentMeaning
target.filethe file whose namespace to change

Precondition

  • The file declares exactly one namespace, block or file-scoped.
  • The namespace differs from the one its folder implies.
  • The folder path gives a valid namespace name.
  • No type in the file shares its name with a type already in the new namespace, and none is a partial type with parts in other files.

Transformation

  • The root namespace is the project's RootNamespace, which defaults to the project name. Folder names have spaces and hyphens replaced by underscores.
  • The namespace declaration is renamed, and every type in it moves with it, with references across the solution updated as in Move Type to Namespace: qualified names are requalified, files using the types gain a using, and the file imports the namespaces its types relied on implicitly.

Preserved

  • The meaning of every name in the solution.
  • The file's layout, comments and namespace form.

Limitations

  • Files declaring several namespaces, or none, are refused rather than restructured.
  • References in documentation comments (cref) are not updated.

Error codes

CodeMeaning
namespace-matches-folderthe namespace already matches the folder
multiple-namespacesthe file declares more than one namespace
no-namespacethe file's types are in the global namespace
type-existsthe new namespace already has a type of the same name
partial-typea type in the file has parts in other files
invalid-namespacethe folder path does not give a valid namespace name

Cases

·

Diffs show each file from before to after. /*[*/ … /*]*/ marks a selection and /*^*/ a caret; the runner removes them before the refactoring runs.

#already-in-sync-rejected

Refuses when the namespace already matches the folder

refusal
TargetBilling/Invoice.cs
Refusesnamespace-matches-folder; every file is left unchanged
Billing/Invoice.csinput
1 namespace Catalog.Billing
2 {
3 public class Invoice
4 {
5 }
6 }

#file-in-folder

Sets the namespace of a file in a folder to the project's root namespace followed by the folder, and imports it where its types are used

success
TargetBilling/Invoice.cs
Billing/Invoice.csmodified
1−namespace Catalog
1+namespace Catalog.Billing
22 {
33 public class Invoice
44 {
55 public Customer Customer { get; set; }
66 }
77
88 public enum InvoiceState
99 {
1010 Draft,
1111 Paid,
1212 }
1313 }
Customer.csmodified
1+using Catalog.Billing;
2+
13 namespace Catalog
24 {
35 public class Customer
46 {
57 public Invoice Latest { get; set; }
68
79 public InvoiceState State => InvoiceState.Draft;
810 }
911 }

#global-namespace-rejected

Refuses a file whose types are in the global namespace, since there is no declaration to change

refusal
TargetBilling/Invoice.cs
Refusesno-namespace; every file is left unchanged
Billing/Invoice.csinput
1 public class Invoice
2 {
3 }

#multiple-namespaces-rejected

Refuses a file declaring more than one namespace, since only one can match the folder

refusal
TargetBilling/Model.cs
Refusesmultiple-namespaces; every file is left unchanged
Billing/Model.csinput
1 namespace Catalog
2 {
3 public class Invoice
4 {
5 }
6 }
7
8 namespace Catalog.Shipping
9 {
10 public class Parcel
11 {
12 }
13 }

#nested-folders-file-scoped

Nested folders become nested namespace parts, and a file-scoped namespace keeps its form; the file imports its old namespace for what it still uses from there

success
TargetTaxes/Rates/Rate.cs
Taxes/Rates/Rate.csmodified
1−namespace Catalog.Billing;
1+using Catalog.Billing;
2+
3+namespace Catalog.Taxes.Rates;
24
35 // Rates are percentages.
46 public class Rate
57 {
68 public Invoice AppliesTo { get; set; }
79
810 public decimal Percent { get; set; }
911 }
Billing/Invoice.csunchanged
11 namespace Catalog.Billing;
22
33 public class Invoice
44 {
55 public decimal Amount { get; set; }
66 }

#project-root

A file at the project root takes the root namespace, here the name of the project it belongs to

success
TargetCore/Money.cs
ProjectsCore; App → Core
App/Till.csmodified
1−using Shop.Values;
1+using Core;
22
33 namespace App
44 {
55 public class Till
66 {
77 public Money Total { get; set; }
88 }
99 }
Core/Money.csmodified
1−namespace Shop.Values
1+namespace Core
22 {
33 public struct Money
44 {
55 public decimal Amount { get; set; }
66 }
77 }

#type-exists-rejected

Refuses when the folder's namespace already has a type with the same name as one in the file

refusal
TargetBilling/Invoice.cs
Refusestype-exists; every file is left unchanged
Billing/Invoice.csinput
1 namespace Catalog
2 {
3 public class Invoice
4 {
5 }
6 }
Billing/Legacy.csinput
1 namespace Catalog.Billing
2 {
3 public class Invoice
4 {
5 }
6 }