question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Reimagine dotnet-new (dotnet new enhanchements 2)

See original GitHub issue

As it currently stands, dotnet new is a good command for people to get started with simple projects. However, it suffers from several things:

  • Templates are coupled with the implementation, thus requiring a new release of the CLI when adding/changing templates
  • Extending templates is tough
  • No support for naming projects via the command line

This issue suggests a new form of dotnet new that solves the above problems. It also replaces the old dotnet/sdk#4695 that will be closed in favor of this one.

/cc @DamianEdwards @piotrpMSFT @Eilon @enricosada

.NET Core CLI: new

The new command is used to create new .NET Core projects. Projects are created using templates installed via NuGet packages.

Templates are laid out in their NuGet packages in a hierarchical fashion that enables the creation of simple trees of templates with categories that are then merged across the installed template packages to create an overall template tree. This tree allows the display of an interactive menu when creating new projects, while also allowing for direct project creation using a template node’s full path, e.g. dotnet new -t aspnetcore/mvc/empty

As templates are in normal NuGet packages and installed into the standard NuGet packages folder, they can depend on other NuGet packages that are used in their templates, such that when they’re installed, all the required packages to create new projects using the contained templates are installed too.

Using the Command Line

Displaying help:

~/code> dotnet new --help
    Usage:
        dotnet new
        dotnet new -t|--template <template/path> [-n|--name <ProjectName>] [[-v|--variable <Name> <Value>] [-v|--variable <Name> <Value>]]
        dotnet new <arguments>

    Arguments:
        -t|--template <template/path>                 The path of the template to use
        -n|--name <ProjectName>                       The name of the new project, created in current folder if not specified
        -v|--variable <Name> <Value>                  Variable to be passed to the template (can be specified more than once)

        -l|--list                                     Lists installed templates
        -i|--install <TemplatePackageId> [version]    Installs templates from a package with optional version
        -i|--install <TemplatePackagePath>            Installs templates from a package
        -u|--uninstall <TemplatePackageId>            Uninstalls a templates package
        -r|--restore                                  Restores installed template packages

Listing installed templates:

~/code> dotnet new --list

MS.DotNetCore.New.Templates 1.0.0
  - Console Application    [console]
  - Class Library          [classlib]

~/code> 

Installing new templates from a package:

~/code> dotnet new --install MS.DotNetCore.New.Templates.AspNetCore 1.0.0
Installing templates from MS.DotNetCore.New.Templates.AspNetCore

Installed 3 templates:
  - ASP.NET Core Empty Application          [aspnetcore/empty]
  - ASP.NET Core MVC Web Site               [aspnetcore/mvc/website]
  - ASP.NET Core MVC Web API Application    [aspnetcore/mvc/webapi]

~/code> dotnet new --list

MS.DotNetCore.New.Templates 1.0.0
  - Console Application    [console]
  - Class Library          [classlib]

MS.DotNetCore.New.Templates.AspNetCore 1.0.0
  - ASP.NET Core Empty Application          [aspnetcore/empty]
  - ASP.NET Core MVC Web Site               [aspnetcore/mvc/website]
  - ASP.NET Core MVC Web API Application    [aspnetcore/mvc/webapi]

~/code> 

Creating a new project with a specific template:

~/code> mkdir MyApp && cd MyApp
~/code/MyApp> dotnet new --template console

Created project "MyApp" in ~/code/MyApp

~/code/MyApp> cd ../
~/code> dotnet new -t console --name MyApp2

Created project "MyApp2" in ~/code/MyApp2

~/code> dotnet new -t aspnetcore/mvc/website --name MyWebApp

Created project "MyWebApp" in ~/code/MyWebApp

~/code> 

Creating a new project using the template menu:

~/code> dotnet new

  Templates
  -----------------------------------
  1. Console Application [console]
  2. Class Library       [classlib]
  3. ASP.NET Core        [aspnetcore]

Select a template [1]: 1
Enter a project name [Project1]: MyApp

Created project "MyApp" in ~/code/MyApp

~/code/MyApp> cd../
~/code> dotnet new

  Templates
  -----------------------------------
  1. Console Application [console]
  2. Class Library       [classlib]
  3. ASP.NET Core        [aspnetcore]

Select a template [1]: 3

  ASP.NET Core Templates
  -----------------------------------
  1. ASP.NET Core Empty Application [aspnetcore/empty]
  2. ASP.NET Core MVC               [aspnetcore/mvc]

Select an ASP.NET Core template [1]: 2

  ASP.NET Core MVC Templates
  -----------------------------------
  1. ASP.NET Core MVC Empty               [aspnetcore/mvc/empty]
  2. ASP.NET Core MVC Web Site            [aspnetcore/mvc/website]
  3. ASP.NET Core MVC Web API Application [aspnetcore/mvc/webapi]

Select an ASP.NET Core MVC template [1]: 2
Enter a project name [Project1]: MyWebApp

Created "MyWebApp" in ~/code/MyWebApp

~/code/MyWebApp> 

Authoring Templates

Templates are placed in NuGet packages in the content/templates folder. Optionally, in the root of the folder is a templates.json file that describes the templates contained and if present is used to enhance the project creation experience.

The layout allows for multi-level category nodes with template nodes as the leaves. In the case a category node contains just a single template node, that template will be automatically selected when the category is chosen.

Example templates.json

Example templates.json for the default templates:

{
    "projectTemplates": {
        "console": {
            "title": "Console Application",
            "children": {
                "csharp": {
                    "title": "Console Application (C#)",
                    "variables": {
                        "framework": {
                            "question": "Please select a target framework",
                            "default": "netstandardapp1.5",
                            "conditions": {
                                "rid": ["win7"]
                            }
                        }
                    }
                }
            }
        },
        "classlib": {
            "title": "Class Library",
            "children": {
                "csharp": {
                    "title": "Class Library (C#)",
                    "variables": {
                        "framework": {
                            "question": "Please select a target framework",
                            "default": "netstandardapp1.5",
                            "conditions": {
                                "rid": ["win7"]   
                            }
                        }
                    }
                }
            }
        }
    }
}

Package Files Layout

The following demonstrates the layout of template NuGet packages. Note how templates from separate packages can share their structure such that they’re templates can occupy the same parts of the resultant installed template “tree”.

~/.nuget/
    packages/
        Microsoft.NETCore.New.Templates/
            templates/
                templates.json
                console/
                    csharp/
                        files/
                            Program.cs
                classlib/
                    csharp/
                        files/
                            project.json
                            Program.cs
        Microsoft.NETCore.New.Templates.VB/
            templates/
                templates.json
                console/
                    vb/
                        files/
                            project.json
                            Program.vb
                classlib/
                    vb/
                        files/
                            projext.json
                            Program.vb
        Microsoft.NETCore.New.Templates.AspNetCore/
            templates/
                templates.json
                aspnetcore/
                    empty/
                        csharp/
                            files/
                                project.json
                                Program.cs
                    mvc/
                        empty/
                            csharp/
                                files/
                                    project.json
                                    Program.cs
                                    Startup.cs
                                    Controllers/
                                        HomeController.cs
                                    wwwroot/
                        website/
                            csharp/
                        webapi/
                            csharp/

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:12
  • Comments:35 (25 by maintainers)

github_iconTop GitHub Comments

8reactions
sayedihashimicommented, Apr 7, 2016

Thoughts on command line project creation

With dotnew new we are interested in enabling an experience for users to create new projects from the command line. Creating projects from the command line is not a new concept, it’s been around for a while especially on the web development side. One example of a successful command line project generator is yeoman. Yeoman is a super popular tool for developers, and if dotnet new is as successful as yeoman, IMO, that would be a really wonderful thing. To enable a meaningful discussion on dotnet new let’s start by taking a look at a typical user experience when using yeoman to create a new project. Below are typical steps a user would take to create a new project from the command line.

Steps to create a new project from yeoman

  1. Install yeoman and it’s dependencies
  2. Search for generator
  3. Install desired generator
  4. Invoke generator
  5. Enter info about the project; i.e. project name, dest dir and other options
  6. Generate the project (happens automatically after the previous step)

From the set of steps above, we can break this down into the following categories.

  1. Template discovery (local and remote)
  2. Command line user interaction - For example; selecting a generator, project name, dest dir, other project options, displaying help, etc.
  3. Going from template -> generated project

I think that dotnet new should focus on the overall end user experience. Which consists of the following, Template discovery and Command line interaction. When the user selects and invokes a template, dotnet new will handle prompting for project properties and then call the generator (with a consistent way to pass project properties). The template should be able to use any “template generator” that it desires. dotnet new will have a template generator available out of the box which can be used. For scenarios in which the default template generator doesn’t meet the needs, it can always be switched out for a different implementation.

In my case I work on delivering templates in the following areas.

  • ASP.NET templates in Visual Studio
  • ASP.NET templates in yo aspnet
  • ASP.NET templates in dotnet new (future)

Today for VS and yo aspnet we have to author templates once for VS and once for yo aspnet. In addition the template infrastructure that we use for the VS side is very fragile and difficult to maintain. Once we enable templates in dotnet new it’s yet another place for us to invest in creating templates. Instead of maintaining three different templates I’d like to have one way to create templates from the command line, and then reuse that tool everywhere. So we author templates once in dotnet new which enables the command line experience with dotnet new. Then in Visual Studio we create “shim templates” which will allow us to present the UI to gather parameters and then call into dotnet new for the project creation process. For yo aspnet we would do a similar thing.

Ideas for implementation

diagram

Brokers are decoupled from specific generators via a set of C# interfaces. This will allow us to maximize reusability of generators in different scenarios including; command line, Visual Studio, yeoman, etc.

Here is a typical user session when creating a new project and a high level of what happens.

Setup

When dotnet-new or Visual Studio are installed the following happens.

  1. Broker add template sources
  2. Broker adds generators

Users can add additional sources to enable using additional generators.

Project Creation

  1. Use uses broker to list templates
    1. Broker “collects” template sources
    2. Broker asks each generator for info on available templates for each template source
  2. User asks broker to create using a selected template (X)
    1. Broker “collects” template sources
    2. Broker finds generator for X
      1. Broker asks each generator if it supports X and stops when a match is found (or some other heuristic to find the single generator to use)
    3. Broker gets info on the given template from the generator
      • Contains metadata to display about the template
      • Contains info about template parameters
  3. Broker gathers info for generation
    1. Get info from the user (i.e. project name, destination, etc.)
    2. Get info from the environment and target
  4. Broker asks the generator to create using a given template
    1. Broker passes the properties acquired from the previous step to the generator to start generation
  5. Broker completes experience
    • VS Broker opens the project in Visual Studio
    • Command line broker displays a success message and more info on next steps

FAQ

Q: Does this mean yo aspnet will go away?

A: Absolutely not. yo aspnet has had some wonderful success it’s not going anywhere. The idea is that we will create a self-contained template tool and then plug that into: VS, dotnet new, yo aspnet, etc. By allowing us to author templates once it will allow us to bring a better experience in yo aspnet. And it will enable us to keep templates in sync at all times across all end-user experiences.

Q: Why not just use yeoman here?

A: Yeoman has a lot of dependencies which are required to use it. It makes sense to have an entry point in yeoman because many people already have it installed (or some of it’s dependencies). There are drawbacks from shipping/using yeoman directly by Visual Studio include the following.

4reactions
enricosadacommented, Mar 25, 2016

About other languages support ( just to check my use case ):

  • templates support multiple languages using subdirectory, nice, 👍 ✅
  • --list should output all templates installed, --list --lang f# only the templates who support f#
  • --list --lang vb should show grouped templates ( like aspnetcore ) if at least one of aspnetcore subtemplates support vb (let’s filter out useless groups, but i’d like aspnet to support f# 😄 )

That’s useful not only for people who use only one language, but for poliglot who have multiple languages installed (i use c# and f#, both a lot)

Now the bonus points (suggestions) for a better cross language experience. The c# is the default language, np about that, there is --lang and it’s ok (was already discussed and it’s ok). But i think we can improve experience for others without changing c# experience:

~/code> dotnet new --list

MS.DotNetCore.New.Templates 1.0.0
  - Console Application    [console] (C#, F#)
  - Class Library              [classlib]  (C#, F#)

MS.DotNetCore.New.Templates.AspNetCore 1.0.0
  - ASP.NET Core Empty Application          [aspnetcore/empty]   (C#, VB)
  • write language name on output, it’s easier to see the default or chosen language
Created C# project "MyApp" in ~/code/MyApp
Created F# project "MyApp" in ~/code/MyApp
Read more comments on GitHub >

github_iconTop Results From Across the Web

Reimagine dotnet-new (dotnet new enhanchements 2)
The new command is used to create new .NET Core projects. Projects are created using templates installed via NuGet packages. Templates are laid ......
Read more >
dotnet new <TEMPLATE> - .NET CLI
The dotnet new command creates new .NET projects based on the specified template.
Read more >
NET default templates for dotnet new - .NET CLI
The following table shows the templates that come pre-installed with the .NET SDK. The default language for the template is shown inside the ......
Read more >
dotnet new install - .NET CLI
The dotnet new install command installs a template package from the PATH or NUGET_ID provided. If you want to install a specific version...
Read more >
dotnet new update - .NET CLI
The dotnet new update command updates installed template packages. The dotnet new update command with --check-only option checks for available ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found