title: Adding an ASPNET API to an existing Worker Service project
body: <p>I currently have a dotnet 5.0 Worker Service project which hosts a background service that executes a line-of-business process at regular intervals. I've managed to fumble my way through setting up a host inside a <code>CreateHostBuilder</code> method, and this is all running fine as an executable inside a docker container.</p>
  <p>However, I would now like to add a HTTP api / ui so that I can expose a &quot;health&quot; endpoint and some pretty web pages that access the same in-process memory as the background service to do things like displaying the contents of an in-memory cache, evicting cache entries, manually triggering a run of the business process etc, and I'm completely lost.</p>
  <p>I'm thinking I just somehow configure an additional hosted service in the <code>ConfigureServices</code> method that binds to a class defined in an ASPNET razor project on ports I specify, but after several attempts I'm a bit stuck with how to start approaching this, let alone make it actually work :-(.</p>
  <p>Specifically, I have a C# project that looks like this:</p>
  <p><strong>MyWorker.csproj</strong></p>
  <pre class="lang-xml prettyprint-override"><code>&lt;Project Sdk=&quot;Microsoft.NET.Sdk.Worker&quot;&gt;
  
    &lt;PropertyGroup&gt;
      &lt;TargetFramework&gt;net5.0&lt;/TargetFramework&gt;
    &lt;/PropertyGroup&gt;
  
    &lt;ItemGroup&gt;
      &lt;PackageReference Include=&quot;Microsoft.Extensions.Configuration.EnvironmentVariables&quot; Version=&quot;5.0.0&quot; /&gt;
      &lt;PackageReference Include=&quot;Microsoft.Extensions.Hosting&quot; Version=&quot;5.0.0&quot; /&gt;
      &lt;PackageReference Include=&quot;Serilog.Extensions.Hosting&quot; Version=&quot;4.0.0-dev-00051&quot; /&gt;
      &lt;PackageReference Include=&quot;Serilog.Formatting.Compact&quot; Version=&quot;1.1.1-dev-00940&quot; /&gt;
      &lt;PackageReference Include=&quot;Serilog.Sinks.Console&quot; Version=&quot;4.0.0-dev-00839&quot; /&gt;
    &lt;/ItemGroup&gt;
  
    &lt;ItemGroup&gt;
      &lt;ProjectReference Include=&quot;..\MyAppCode\MyAppCode.csproj&quot; /&gt;
    &lt;/ItemGroup&gt;
  
  &lt;/Project&gt;
  </code></pre>
  <p>and a <strong>Program.cs</strong> that looks like this:</p>
  <pre class="lang-cs prettyprint-override"><code>        public static void Main(string[] args)
          {
  
              Program.InitSerilog();
              Program.CreateHostBuilder(args).Build().Run();
  
          }
  
          public static void InitSerilog()
          {
              ... do stuff ...
          }
  
          public static IHostBuilder CreateHostBuilder(string[] args)
          {
              return new HostBuilder()
                  // worker service config
                  .ConfigureLogging((context, builder) =&gt;
                  {
                      builder.SetMinimumLevel(LogLevel.Trace);
                  })
                  .ConfigureServices(services =&gt;
                  {
                      services.AddHostedService&lt;MyAppService&gt;();
                      services.AddSingleton&lt;AppSettings&gt;(
                          serviceProvider =&gt; { return Program.CreateAppSettings(); }
                      );
                  })
                  .UseSerilog();
          }
  
          private static AppSettings CreateAppSettings()
          {
              ... bind to environment variables and return ...
          }
  
      }
  </code></pre>
  <p>Finally, my existing background service looks like this:</p>
  <pre class="lang-cs prettyprint-override"><code>    public sealed class MyAppService: BackgroundService
      {
  
          public MyAppService(ILogger&lt;MyAppService&gt; logger, AppSettings appSettings)
              : base()
          {
              ... do stuff ...
          }
  
          protected override async Task ExecuteAsync(CancellationToken stoppingToken)
          {
              ... keep doing the main business process in a timed loop ...
          }
  
          #endregion
      }
  </code></pre>
  <p>I've found a lot of examples of how to add a worker service to an existing ASPNET project, or how to host an ASPNET project as a Windows Service, but nothing on how to add an ASPNET site listener to an existing Worker Service.</p>
  <p>What I'd <em>like</em> to be able to do is build the web ui / api in a new c# project and somehow just plumb it in to the existing Program.cs so it listens on a specified port while the main BackgroundService is running, but maybe I'm just approaching this all wrong?</p>
  <p>Note - it's possible I undid some of the default &quot;just works&quot; magic in the <code>CreateHostBuilder</code> method while I was tinkering, so feel free to tell me to put that back to the default if that's the easy answer :-).</p>
  <p>Any help / pointers appreciated...</p>