templating icon indicating copy to clipboard operation
templating copied to clipboard

Consider adding a class item template

Open kendrahavens opened this issue 5 years ago • 7 comments

Add dotnet new class

dotnet new class is an expected path to new users. Without it, we assume the user adds new .cs file through their file explorer or their editor. I'm contributing to docs to make this clearer, but ideally it'd be a simple command that creates a Class1.cs file in the current directory.

using System;

namespace <ParentFolder>
{
    public class Class1
    {

    }
}

Customer filed issue on this.

kendrahavens avatar Dec 04 '18 17:12 kendrahavens

Regarding the namespace & class name: I think we should have input params for both the class name and the namespace. The CLI doesn't have the capability to inspect the directory and create a parameter value based on it. But the template engine hosting in VS Code may be capable of looking at the directory structure, and passing along the directory as the namespace parameter value. I'm not sure this is the case, we'd need to find out from someone involved in the VS Code integration of templating. Alternately, there could be user inputs in the VS Code UI for both the class name and namespace - the user may want to have control over the namespace value.

seancpeters avatar Dec 05 '18 21:12 seancpeters

The cli uses the name of the parent directory as the name of the .csproj and the Namespace when a project is created.

image

though I absolutely agree users should be able to use the -n flag for the class name.

kendrahavens avatar Dec 06 '18 02:12 kendrahavens

Ah, for the parent directory, you mean the directory the project is being created in (class item in this case). That we can do, I was mis-thinking a directory one up in the path - which really makes no sense :). When niether the -o nor the -n option are provided, the current directory is implicitly used as the value of "name" parameter, which is usually used to replace the namespace. That's a function of how the template is authored - easy enough to setup for this purpose.

seancpeters avatar Dec 06 '18 02:12 seancpeters

This is actually more interesting than it would seem and is the reason we haven't approached calculating the namespace in the past (excepting for providing value forms that "namespace-ify" the value of name). If within the HelloWorld directory (containing the csproj - which could set a RootNamespace element that should ideally be respected) there's another directory called Models for instance, the expected namespace would be HelloWorld.Models or, if RootNamespace were set in HelloWorld.csproj to be Hello.World, the new expected namespace would be Hello.World.Models. It just happens that the current name chosen for root namespace if not explicitly provided is the exact file name of the csproj without modification (which was the source of a bug on the VS tooling side for project names containing dashes & worked around by conditionally setting a RootNamespace element in generated csproj files if the namespace we use when generating the classes within the project differ from the raw value of the name parameter).

For now, I believe the best course of action is to simply provide a --namespace parameter that allows the user to set it & consider adding a "default value source" to parameters that could do whatever flavor of calculation is desired for that template.

Possible behaviors for C#:

  • Classes are generated with the same namespace as their folder name (escaped for namespace) - easiest
  • Classes are generated with the same namespace as their containing project name (consistent behavior with namespace generation if the class is a peer to the project file) - second easiest
  • 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
  • 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
  • Classes are generated with the same namespace as the majority of the files in the same directory, if there aren't any or there's not a clear majority, using one of the above approaches for determining the "default" namespace

All of the above options should be subject to an explicit user override as well

mlorbetske avatar Dec 07 '18 18:12 mlorbetske

I'd be very happy with the first and easiest option you've listed.

Classes are generated with the same namespace as their folder name (escaped for namespace) - easiest

And I agree that providing a --namespace flag is good. I'm not familiar with how popular it is for cli users to want to specify a "default value source" so they can customize generated names. I'd probably wait to do any extra work until there is a customer request. (Of course, if it's easy, why not?)

We can alter behavior if we get feedback on it. The main goal is to make adding a class as simple as possible without the user needing to leave their command-line initialization context.

kendrahavens avatar Dec 07 '18 21:12 kendrahavens

Any updates?

waynebaby avatar Sep 02 '20 04:09 waynebaby

We're blocked on this until #3829 is completed, but after that we definitely should be able to derive enough project-level context to create a new class file:

  • with a given name
  • using the namespace of the project
  • either in top-level namespace or nested-namespace mode based on the preference of the project

baronfel avatar Apr 12 '22 19:04 baronfel

C# class template was implemented in https://github.com/dotnet/sdk/pull/29655. VB template will be implemented later.

vlada-shubina avatar Dec 27 '22 10:12 vlada-shubina

Any chance we will get support for any one of these:

  • 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
  • Classes are generated with the same namespace as the majority of the files in the same directory, if there aren't any or there's not a clear majority, using one of the above approaches for determining the "default" namespace

There is alreay a fitting binding existing that can be used as defined here ("binding": "namespace") which is currently for Visual Studio only which is funny as Visual Studio does not yet support dotnet new item templates.

Mrxx99 avatar Jan 16 '23 20:01 Mrxx99

Hi @Mrxx99 ,

I moved your suggestion to a separate ticket for further discussion. The third point isn't included due to existing parser restrictions and the ratio between gain/loss for the implementation.

YuliiaKovalova avatar Jan 30 '23 12:01 YuliiaKovalova