A project option is an option provided to the `dotnet new` command that affects the generated project in some way.
In this example, we add a new project option named `hello-world` that logs a hello message when our application starts up.
Sample output of a generated project with the new `hello-world` project option:
```
$ dotnet new steeltoe-webapi --output MyHelloWorldApp --hello-world
$ dotnet run --project MyHelloWorldApp
info: MyHelloWorldApp.Startup[0]
Hello World from MyHelloWorldApp
...
```
We'll use a [TDD](https://en.wikipedia.org/wiki/Test-driven_development) style to implement our new project option.
A major tenet of TDD is that you should first see your tests fail prior to making or implementing changes.
The nature of template development makes honoring this tenet a bit cumbersome, however we'll attempt to placate the TDD tenet somewhat by using 2 branches:
* one to write our tests and ultimately implement our project option
* one to develop our option to satisfy the tests
The general flow of the implementation is:
* create a basic test and define the option so that the test passes
* implement the template changes for the option and add tests to verify those changes
$ git branch hello-world # ultimate branch for our new option
$ git branch hello-world-dev # temporary development branch
```
### Creating a Test Class for the Project Option
Switch to the ultimate branch:
```
$ git switch hello-world
```
The `hello-world` project option is a boolean option, which in use will look something like:
```
$ dotnet new steeltoe-webapi # hello-world is false
$ dotnet new steeltoe-webapi --hello-world # hello-world is true
$ dotnet new steeltoe-webapi --hello-world false # hello-world is false
$ dotnet new steeltoe-webapi --hello-world true # hello-world is true
```
There are several abstract test classes in the project to assist in option development.
The abstract class [ProjectOptionTest](https://github.com/steeltoeoss-incubator/DotNetNewTemplates/blob/main/test/DotNetNew.SteeltoeWebApi.Test/ProjectOptionTest.cs) should be used for project options such as `hello-world`.
The `ProjectOptionTest` constructor takes 3 arguments:
* option name
* option description
* logger (injected)
The description is what will be output by the `dotnet new` help engine.
However, we only want projects that are generated with the `hello-world` option to have these changes so we'll use the C# `HelloWorldOption` preprocessor directive around our new code.
Note there are two `Configure` method signatures; one for `netcoreapp2.1` and one for everything else.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILogger<Startup> logger)
#else
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
#endif
#else
#if (HelloWorldOption)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
#else
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
#endif
#endif
{
#if (HelloWorldOption)
logger.LogInformation("Hello, World, from {Name}", "Company.WebApplication1");
#endif
if (env.IsDevelopment())
...
```
Create a couple projects to try out the `hello-world` option.
```
$ dotnet new steeltoe-webapi --output MyHelloWorldApp --hello-world
▶ dotnet run --project MyHelloWorldApp
info: MyHelloWorldApp.Startup[0]
Hello, World, from MyHelloWorldApp
...
$ dotnet new steeltoe-webapi --output MyHelloWorldApp21 --hello-world --framework netcoreapp2.1
$ dotnet run --project MyHelloWorldApp21
info: MyHelloWorldApp21.Startup[0]
Hello, World, from MyHelloWorldApp21
...
```
Add the changes to the temporary branch:
```
$ git src/DotNetNew.WebApi/CSharp/Startup.cs
$ git commit -m'Implement the hello-world option'
```
### Add Project Option Behavior Tests
Switch to the ultimate branch.
```
$ git switch hello-world
```
The `ProjectOptionTest` abstract class provides a _ProjectGeneration_ test category that tests an option with each valid combination of Steeltoe version and .NET framework.
The tests focus on generated project code, e.g. packages in the `.csproj` file and snippets in `Startup.cs`.