Note: what you'll find below are just some ideas. I'm writing these down so that I can share it at https://github.com/dotnet/cli/issues/2052 with the goal to change how we are approaching templates. I'm not directly woring in this area. However, I am responsible for ASP.NET template content in Visual Studio and yo aspnet
.
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.
- Install yeoman and it's dependencies
- Search for generator
- Install desired generator
- Invoke generator
- Enter info about the project; i.e. project name, dest dir and other options
- Generate the project (happens automatically after the previous step)
From the set of steps above, we can break this down into the following categories.
- Template discovery (local and remote)
- Command line user interaction - For example; selecting a generator, project name, dest dir, other project options, displaying help, etc.
- 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.
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.
When dotnet-new
or Visual Studio are installed the following happens.
- Broker add template sources
- Broker adds generators
Users can add additional sources to enable using additional generators.
- Use uses broker to list templates
- Broker "collects" template sources
- Broker asks each generator for info on available templates for each template source
- User asks broker to create using a selected template (
X
)- Broker "collects" template sources
- Broker finds generator for
X
- 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)
- Broker asks each generator if it supports
- Broker gets info on the given template from the generator
- Contains metadata to display about the template
- Contains info about template parameters
- Broker gathers info for generation
- Get info from the user (i.e. project name, destination, etc.)
- Get info from the environment and target
- Broker asks the generator to create using a given template
- Broker passes the properties acquired from the previous step to the generator to start generation
- Broker completes experience
- VS Broker opens the project in Visual Studio
- Command line broker displays a success message and more info on next steps
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.
- Yeoman has a lot of dependencies. This increases the download size, install time, and also introduces issues where each dependency needs to be reviewed to ensure we don't violate any licenses.
- If a bug is found in a dependency it may take a while for that to get fixed, especially if it's a platform specific bug. For example OmniSharp/generator-aspnet#351, which was opened in Sept 2015, and we are just now able to get the fix out.
- In addition to this, authoring templates can be made a lot easier than what's required with yeoman today.
Awesome ideas!
I think two important points that Yeoman right now allows are:
The later is a bit tedious since there is no notification whatsoever if any given template has a new version, given that this would be a command-line tool maybe a
dotnet new update
sort of system could be allowed to trigger a global template update?Not sure how user-created templates could be handled, but to toss an idea, when I author new Visual Studio Code Extensions, they have a publishing command-line tool so maybe something like that could be used? They have it tied to the marketplace too.