Skip to content
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

Improve root namespace definition for templates #6010

Open
YuliiaKovalova opened this issue Jan 30, 2023 · 11 comments
Open

Improve root namespace definition for templates #6010

YuliiaKovalova opened this issue Jan 30, 2023 · 11 comments
Labels
feature The issue defines new feature. gathering-feedback The issue requires feedback in order to be planned, please comment if the feature is useful for you Priority:2 Work that is important, but not critical for the release triaged The issue was evaluated by the triage team, placed on correct area, next action defined.

Comments

@YuliiaKovalova
Copy link
Member

Is your feature request related to a problem? Please describe.

Feature request

Describe the solution you'd like.

  • Classes are generated with the same namespace as their containing project name but with additional segments added for any subfolders from the directory containing the project file to the class file)
  • Classes are generated with the same namespace as their containing project name unless root namespace is specified in the project file addition additional segments to the namespace for each folder
    Based on Consider adding a class item template #1713

Additional context

No response

@egvijayanand
Copy link
Contributor

Yes, the namespace needs to get synced with the containing folder name included (relative to the project file).

For example, BaseViewModel is a type created under the ViewModels folder, but when the parameter is defined as mentioned in this Docs page, the generated namespace is either the project name or the value defined for RootNamespace property in the project file.

namespace MyApp;

public class BaseViewModel
{
}

@maridematte maridematte added the triaged The issue was evaluated by the triage team, placed on correct area, next action defined. label Feb 7, 2023
@YuliiaKovalova YuliiaKovalova added the gathering-feedback The issue requires feedback in order to be planned, please comment if the feature is useful for you label Feb 28, 2023
@YuliiaKovalova YuliiaKovalova added the feature The issue defines new feature. label May 18, 2023
@smitpatel
Copy link
Member

We dotnet new class to generate new class in C# dev kit and we have received multiple feedback from customers that they would like the namespace to be aligned with folder. We should try to make best effort for the easy common case to get sub-namespaces. From CLI perspective, I can also see that people could be invoking command and putting output in directory which is not subfolder inside folder containing project file (through output or project switch), we can just use rootnamespace in such cases when we cannot compute relative path.

@henriqueTr25
Copy link

henriqueTr25 commented Jan 5, 2024

Any updates on that ?

@sayedihashimi
Copy link
Member

sayedihashimi commented Jan 6, 2024

I have a sample of a Class template which gets the projects rootnamespace and uses that as the namespace declaration. Sample is at https://github.com/sayedihashimi/template-sample/blob/main/src/contoso-templatepack/content/item-templates/classfile/.template.config/template.json, I've pasted the template.json below. This doesn't solve adding the relative folder path though.

I believe this only works with .net 8+ but could be wrong on that. @baronfel will know which version the support is in.

{
  "$schema": "http://json.schemastore.org/template",
  "$comment": "Code for this template is available at https://github.com/sayedihashimi/template-sample",
  "author": "Contoso",
  "classifications": ["template"],
  "name": "contoso-class",
  "description": "Contoso item template for a class file with a Contoso approved license.",
  "identity": "Contoso.Templates.Item.ClassWithLicense",
  "shortName": "cclass",
  "tags": {
    "language": "C#",
    "type": "item"
  },
  "sourceName": "SampleClassFile",
  "defaultName": "MyClass",
  "symbols": {
    "DefaultNamespace": {
      "type": "bind",
      "binding": "msbuild:RootNamespace",
      "replaces": "Contoso.Starter",
      "defaultValue": "Contoso"
    }
  },
  "primaryOutputs": [
    {
      "path": "SampleClassFile.cs"
    }
  ],
  "postActions": [
    {
      "id": "openInEditor",
      "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")",
      "description": "Opens generated files in the editor",
      "manualInstructions": [],
      "actionId": "84C0DA21-51C8-4541-9940-6CA19AF04EE6",
      "args": {
        "files": "0"
      },
      "continueOnError": true
    }
  ]
}

In the sample above you can see the DefaultNamespace symbol which replaces the string Contoso.Starter in the template files that are generated.

@egvijayanand
Copy link
Contributor

egvijayanand commented Jan 8, 2024

@sayedihashimi While using the parameter $rootnamespace$ in the VS native templates, it automatically takes the containing folder as part of the namespace emitted in the output. (Link 1).

https://github.com/egvijayanand/dotnet-maui-templates/blob/e111e3c33dc2ee22206a52d1fce716049c949cc4/src/ItemTemplates/PartialClass/MyClass.cs#L7

https://github.com/egvijayanand/dotnet-maui-templates/blob/e111e3c33dc2ee22206a52d1fce716049c949cc4/src/MauiTemplatesCLI/MyClass/.template.config/template.json#L24

For example, assume Contoso as the root namespace defined and the item is created inside the Models folder, then the value emitted would be Contoso.Models. Whereas with this modern CLI templating, it stops with Contoso, and the containing folder is ignored. Additional work even after automation. Painful for multi-file templates like XAML and its code-behind, have to update it in different locations. The folder path relative to the project file should also be included in the namespace emitted. (Link 2).

Kindly look into it.

@sayedihashimi
Copy link
Member

Thanks, yes we will need to figure out a way to get the relative folder path into the generated namespace. I will discuss with the team to see what options we have.

@egvijayanand
Copy link
Contributor

egvijayanand commented Jan 17, 2024

How to get the current path of the "dotnet new" while processing the template, like the bind symbol (host/env)?

Need the current directory while processing an item template.

Any possibility of using Environment.CurrentDirectory or something of that sort?

Any input would be highly appreciated.

@sayedihashimi
Copy link
Member

A few of us discussed this today. Unfortunately @baronfel was unavailable for that discussion, but we will need to sync with him as well. Below is a brief summary of what we discussed and the two options that were most obvious.

Proposal 1

  • Modify item templates to include a new parameter named Namespace.
    • The user can specify the value on the CLI but it needs to be a C# safe value
  • Modify item templates to have a DefaultNamespace symbol if it doesn’t already
    • Add a new computed symbol, maybe named ResolvedNamespace.
  • If the user specifies the value for Namespace that is used otherwise DefaultNamespace is used. We will use coalesce to implement this.
  • Have the C# Dev Kit Template Engine host to compute the final value including the namespace and the relative folder path and pass it in as the value for Namespace
    • Visual Studio already does this and for the time being many item templates that are used are authored with vstemplate tech and not Template Engine

Pros

  • No code changes to the Template Engine/SDK

Cons

  • Requires changes to templates which means that the user will need to have that version or higher to see these benefits

Proposal 2

  • Add a parameter named Namespace if the template doesn't already have it
    • Some of our templates already have this (for ex: Razor Page template)
  • Create a new generator in the Template Engine which knows how to compute the full value for the namespace parameter
  • Update templates to have a symbol that uses the new generator to compute the default value
  • Add a new parameter named Namespace
    • Users can use this to override the value when calling dotnet new on the CLI

Pros

  • dotnet new users would get the correct value for namespace including the relative folder path
  • Less work in each Template Engine host
  • Easy to add support in other templates

Cons

  • Requires changes to the Template Engine which means we need to rev the SDK
    • Only people who install this version or higher, will get the correct value for the namespace in the generated files
  • Requires changes to templates

@MithrilMan
Copy link

meanwhile could we do something e.g. using postActions?
any workaround? any new consideration?
thanks

@akachida
Copy link

Is this issue dead? This is REALLY annoying, mostly when starting a new project.

@LucasBLs
Copy link

Essa questão está morta? Isso é REALMENTE irritante, principalmente ao iniciar um novo projeto.

This is really annoying. What has been helping me is the 'C# Extensions v1.7.3'; it can fetch the namespace normally...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature The issue defines new feature. gathering-feedback The issue requires feedback in order to be planned, please comment if the feature is useful for you Priority:2 Work that is important, but not critical for the release triaged The issue was evaluated by the triage team, placed on correct area, next action defined.
Projects
None yet
Development

No branches or pull requests

9 participants