diff --git a/src/ProjectTemplates/README.md b/src/ProjectTemplates/README.md
new file mode 100644
index 0000000000..ae1f73d94d
--- /dev/null
+++ b/src/ProjectTemplates/README.md
@@ -0,0 +1,10 @@
+# Templates
+
+## Getting Started
+These are project templates which are used in .NET Core for creating ASP.NET Core applications.
+
+## Building Templates
+- Run `build.cmd -Pack` in the repository root to build all of the dependencies.
+- Run `build.cmd` in this directory will produce NuGet packages for each class of template in the artifacts directory. These can be installed via `dotnet new -i {nugetpackage path}`
+- The ASP.NET localhost development certificate must also be installed and trusted or else you'll get a test error "Certificate error: Navigation blocked".
+- You also need to get the packages these templates depend on into your package cache or else `dotnet new` restore will fail. The easiest way to get them to run is by letting the build run at least 1 test. Note currently some packages are missed. https://github.com/aspnet/AspNetCore/issues/7388
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj b/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj
index 75423fcdc0..44fba9a0dc 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj
+++ b/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj
@@ -16,6 +16,7 @@
MicrosoftEntityFrameworkCoreSqlitePackageVersion=$(MicrosoftEntityFrameworkCoreSqlitePackageVersion);
MicrosoftEntityFrameworkCoreSqlServerPackageVersion=$(MicrosoftEntityFrameworkCoreSqlServerPackageVersion);
MicrosoftEntityFrameworkCoreToolsPackageVersion=$(MicrosoftEntityFrameworkCoreToolsPackageVersion);
+ MicrosoftExtensionsHostingPackageVersion=$(MicrosoftExtensionsHostingPackageVersion);
MicrosoftNETCoreAppPackageVersion=$(MicrosoftNETCoreAppPackageVersion);
@@ -45,6 +46,7 @@
+
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Worker-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/Worker-CSharp.csproj.in
new file mode 100644
index 0000000000..307888d48d
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/Worker-CSharp.csproj.in
@@ -0,0 +1,13 @@
+
+
+
+ netcoreapp3.0
+ Exe
+ True
+ Company.Application1
+
+
+
+
+
+
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/dotnetcli.host.json
new file mode 100644
index 0000000000..b1cf98e39b
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/dotnetcli.host.json
@@ -0,0 +1,19 @@
+{
+ "$schema": "http://json.schemastore.org/dotnetcli.host",
+ "symbolInfo": {
+ "Framework": {
+ "longName": "framework"
+ },
+ "skipRestore": {
+ "longName": "no-restore",
+ "shortName": ""
+ },
+ "ExcludeLaunchSettings": {
+ "longName": "exclude-launch-settings",
+ "shortName": ""
+ }
+ },
+ "usageExamples": [
+ ""
+ ]
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/template.json
new file mode 100644
index 0000000000..4a12b88ea2
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/template.json
@@ -0,0 +1,90 @@
+{
+ "$schema": "http://json.schemastore.org/template",
+ "author": "Microsoft",
+ "classifications": [
+ "Common",
+ "Worker"
+ ],
+ "name": "Worker Service",
+ "generatorVersions": "[1.0.0.0-*)",
+ "description": "An empty project template for creating a worker service.",
+ "groupIdentity": "Microsoft.Worker.Empty",
+ "precedence": "5000",
+ "identity": "Microsoft.Worker.Empty.CSharp.3.0",
+ "shortName": "worker",
+ "tags": {
+ "language": "C#",
+ "type": "project"
+ },
+ "sourceName": "Company.Application1",
+ "preferNameDirectory": true,
+ "guids": [
+ "53bc9b9d-9d6a-45d4-8429-2a2761773502"
+ ],
+ "sources": [
+ {
+ "modifiers": [
+ {
+ "condition": "(ExcludeLaunchSettings)",
+ "exclude": [
+ "Properties/launchSettings.json"
+ ]
+ }
+ ]
+ }
+ ],
+ "symbols": {
+ "ExcludeLaunchSettings": {
+ "type": "parameter",
+ "datatype": "bool",
+ "defaultValue": "false",
+ "description": "Whether to exclude launchSettings.json from the generated template."
+ },
+ "Framework": {
+ "type": "parameter",
+ "description": "The target framework for the project.",
+ "datatype": "choice",
+ "choices": [
+ {
+ "choice": "netcoreapp3.0",
+ "description": "Target netcoreapp3.0"
+ }
+ ],
+ "replaces": "netcoreapp3.0",
+ "defaultValue": "netcoreapp3.0"
+ },
+ "copyrightYear": {
+ "type": "generated",
+ "generator": "now",
+ "replaces": "copyrightYear",
+ "parameters": {
+ "format": "yyyy"
+ }
+ },
+ "skipRestore": {
+ "type": "parameter",
+ "datatype": "bool",
+ "description": "If specified, skips the automatic restore of the project on create.",
+ "defaultValue": "false"
+ }
+ },
+ "primaryOutputs": [
+ {
+ "path": "Company.Application1.csproj"
+ }
+ ],
+ "defaultName": "Application1",
+ "postActions": [
+ {
+ "condition": "(!skipRestore)",
+ "description": "Restore NuGet packages required by this project.",
+ "manualInstructions": [
+ {
+ "text": "Run 'dotnet restore'"
+ }
+ ],
+ "actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025",
+ "continueOnError": true
+ }
+ ]
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/vs-2017.3.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/vs-2017.3.host.json
new file mode 100644
index 0000000000..ca9a19bb4a
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/vs-2017.3.host.json
@@ -0,0 +1,39 @@
+{
+ "$schema": "http://json.schemastore.org/vs-2017.3.host",
+ "name": {
+ "text": "Worker Service",
+ "package": "{0CD94836-1526-4E85-87D3-FB5274C5AFC9}",
+ "id": "1011"
+ },
+ "description": {
+ "text": "An empty project template for creating a worker service.",
+ "package": "{0CD94836-1526-4E85-87D3-FB5274C5AFC9}",
+ "id": "1012"
+ },
+ "order": 100,
+ "icon": "vs-2017.3/Empty.png",
+ "learnMoreLink": "https://go.microsoft.com/fwlink/?linkid=2072778",
+ "uiFilters": [ "oneaspnet" ],
+ "supportsDocker": true,
+ "legacyTemplateIdentity": "Microsoft.NetCore.CSharp.EmptyWorker",
+ "supportedAuthentications": [
+ {
+ "auth": "None",
+ "authenticationType": "NoAuth",
+ "allowUnsecured": true
+ }
+ ],
+ "ports": [
+ {
+ "name": "HttpPort",
+ "useHttps": false
+ },
+ {
+ "name": "HttpsPort",
+ "useHttps": true
+ }
+ ],
+ "excludeLaunchSettings": false,
+ "minFullFrameworkVersion": "4.6.1",
+ "disableHttpsSymbol": "NoHttps"
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/vs-2017.3/Empty.png b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/vs-2017.3/Empty.png
new file mode 100644
index 0000000000..ea4b7e2492
Binary files /dev/null and b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/vs-2017.3/Empty.png differ
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/Program.cs
new file mode 100644
index 0000000000..91dcb319bb
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/Program.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+
+namespace Company.Application1
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ CreateHostBuilder(args).Build().Run();
+ }
+
+ public static IHostBuilder CreateHostBuilder(string[] args) =>
+ Host.CreateDefaultBuilder(args)
+ .ConfigureServices(services =>
+ {
+ services.AddHostedService();
+ });
+ }
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/Worker.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/Worker.cs
new file mode 100644
index 0000000000..7b8622960d
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/Worker.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+
+namespace Company.Application1
+{
+ public class Worker : BackgroundService
+ {
+ private readonly ILogger _logger;
+
+ public Worker(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
+ {
+ while (!stoppingToken.IsCancellationRequested)
+ {
+ _logger.LogInformation($"Worker running at: {DateTime.Now}");
+ await Task.Delay(1000, stoppingToken);
+ }
+ }
+ }
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/appsettings.Development.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/appsettings.Development.json
new file mode 100644
index 0000000000..e203e9407e
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Debug",
+ "System": "Information",
+ "Microsoft": "Information"
+ }
+ }
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/appsettings.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/appsettings.json
new file mode 100644
index 0000000000..56b30baa59
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/appsettings.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ }
+}