Project-system: Change default namespace associated to a folder when creating new class

Created on 26 Aug 2019  路  18Comments  路  Source: dotnet/project-system

_This issue has a corresponding ticket on Developer Community. Please vote and comment there to make sure your voice is heard._


It would be nice if there is a feature to set a default namespace for each folder when creating a new class. For example, if we have the following file structure:

     MyFolder
          MyClass1

Then if we create MyClass2 under MyFolder, the created class will be under the MyProject namespace instead of MyProject.MyFolder.

Additional references: https://stackoverflow.com/questions/1317901/change-default-namespace-when-creating-class-in-folder-visual-studio

Feature Request Triage-Approved

Most helpful comment

ReSharper stores this data in their own resource file, outside of the project file. We would want to store it in the project file directly.

For example:

<ItemGroup>
  <Folder Include="Models\" IsNamespaceProvider="False" />
</ItemGroup>

Currently this Folder item is removed as soon as a class is added to that folder. We'd need to ensure Folder items with custom metadata are not removed in such cases.

All 18 comments

To paraphrase, the request is to be able to mark a folder with metadata to stop it from participating in namespace construction.

Yep interesting and reasonable request. We don't have the ability to associate metadata with a folder in CPS - other than empty folders, they don't have a item representation, so we'd need to introduce that.

@davkean You might want to look at this feedback post I created. Admittedly, this was before I realized that ReSharper was doing part of this...
https://developercommunity.visualstudio.com/content/problem/621033/adding-a-class-does-not-honor-namespace-provider-s.html

So somehow ReSharper is keeping meta data on the folder to determine if the folder name should be part of the namespace. If I add a new class via ReSharper (which I never do) it's honored. If I use VS to add a class, it's not honored (not surprisingly in hindsight).

Here is a small screenshot of a folder being selected and ReSharper's added property "Namespace Provider"

Folder Properties

Now, I am not expecting you to code to ReSharper's standard, but when you start working on this you may let them know so they can take it into account in their code. I would hate to see double folder properties and have to set them both not knowing which one is which.

ReSharper stores this data in their own resource file, outside of the project file. We would want to store it in the project file directly.

For example:

<ItemGroup>
  <Folder Include="Models\" IsNamespaceProvider="False" />
</ItemGroup>

Currently this Folder item is removed as soon as a class is added to that folder. We'd need to ensure Folder items with custom metadata are not removed in such cases.

This is useful when we want to add all of our class extensions in an Extensions folder but want them all to be in the main namespace.

I think the best option would be to allow us to bring up the Properties window and edit a DefaultNameSpace property on the folder.

@jinujoseph Are you tracking anything similar on your side?

This is useful when we want to add all of our class extensions in an Extensions folder but want them all to be in the main namespace.

Agree, this is quite common case when some folder need to be in parent namespace.
My thought:

  1. Create Virtual Folder in project (like solution virtual folder) with unique icon.
  2. Or ignore folder with special prefix like maybe @Extensions or _Extensions.
    both way are very clear to indicate all items in the folder are using parent namespace, which I think is better then ReSharper way.

Any news on this? Is it being considered for a future update?

This would be really useful!

Adding metadata to any C# Project folder to override default folder-structure based namespace with:

  • default namespace: (empty)
    would follow default functionality
  • absolute namespace: /Parent/Child
    allows full namespace override
  • relative namespace: Child or ./Child or ../../Child
    that would resolve based on parent Namespace (which obviously can be overridden itself).
  • no namespace: -
    this would use parent namespace without child participating in the name construction

And any file added to that folder will have the namespace based on the override when file is created. And this should only apply to new files. If you change the folder's virtual namespace, there should be no sync for existing files with the old namespace. That's the developer's job to rename.

This would really help because often, you find yourself wanting to structure (1 or multiple folders deep) files but need them all in the same namespace. It's quite a headache.

In our case we have a project where we structure functionality under a seperate folder. Like everything for Customer is being filed under the Customer folder. But since there's also a DTO called Customer in another project we use the CustomerModule namespace for the classes in the Customer folder.

Now each time you add a new class it's being added in the Customer namespace. It would be handy if you could have a folderconfig or maybe projectconfig file (one in the entire project) where you could specify the options for class files for a specific folder/project

In addition to specifying that a folder does not participate in namespace construction, I can see it being useful to also specify the full namespace for a given folder, such that it ignores any project-level namespace and ancestor folder names.

This is not flexible

<ItemGroup>
  <Folder Include="Models\" IsNamespaceProvider="False" />
</ItemGroup>

Should be

<ItemGroup>
  <Folder Include="Models\" Namespace="whatever I want or empty" />
</ItemGroup>

@MhAllan both have merits. Specifying the full namespace on folders is harder to maintain when moving folders or renaming ancestors.

It should be, If I set a Namespace, that won't change by changing the hierarchy or renaming ancestors.

@drewnoakes that's the whole point of the request, to break the link between namespace and folder location.

@drewnoakes that's the whole point of the request, to break the link between namespace and folder location.

Indeed. But there are multiple potential implementations, each with strengths and weaknesses.

Edit: I can see why my comment could be confusing out of context. I was referring to the idea of specifying the full path on each folder, rather than just opting a particular folder out of namespace construction.

I like these Examples:

1.Dynamic with folder name:

<ItemGroup>
  <Folder Include="Models\" Namespace="Example.Sale.Core.[FolderName]" />
</ItemGroup>

2.Static namespace:

<ItemGroup>
  <Folder Include="Models\" Namespace="Example.Sale.Core.Models" />
</ItemGroup>

3.Default from project namespace:

<ItemGroup>
  <Folder Include="Models\"/>
</ItemGroup>

I think * would be better than [FolderName]

Was this page helpful?
0 / 5 - 0 ratings