I was migrating an ASP.NET Core App to the Worker Service template and was intending to keep the Startup
code.
However after
within Program I kept the CreateHostBuilder as described on the MS Docs:
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureWebHostDefaults(
webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureServices(
services =>
{
services.AddHostedService<Worker>();
});
while debugging, the ConfigureServices
is being called
public void ConfigureServices(IServiceCollection services)
but the Configure
within the Startup, is not reached / called
public void Configure(IApplicationBuilder app)
before it crashes calling Run()
.
I also tried this with the same result:
public static IHostBuilder CreateHostBuilder(string[] args)
=> Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureWebHostDefaults(webBuilder => webBuilder.Configure(Startup.Configure))
.ConfigureServices(
services =>
{
Startup.ConfigureServices(services);
services.AddHostedService<Worker>();
});
The interesseting part is that the following code actually calls the Startup.Configure(IApplicationBuilder app)
:
public static IHostBuilder CreateHostBuilder(string[] args)
=> Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureWebHostDefaults(webBuilder => webBuilder.Configure(Startup.Configure));
As soon as I am adding ConfigureServices
it skips the IApplicationBuilder
configuration call.
Am I missing something or what is the suggested way to achieve this?
Edit:
the exact error is:
InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Builder.IApplicationBuilder' while attempting to activate 'Kledex.Extensions.KledexAppBuilder'.
stack trace:
at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable'1 serviceDescriptors, ServiceProviderOptions options) at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options) at Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder) at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter'1.CreateServiceProvider(Object containerBuilder) at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider() at Microsoft.Extensions.Hosting.HostBuilder.Build()
the error happens as soon as it reaches CreateHostBuilder(args).Build().Run();
and tries to resolve the registered services, while the above one has a dependency to some config app.UseSomething();
within the Startup.Configure()
method.
A breakpoint in Startup.Configure()
doesn't get hit.
Given that you are trying to configure web host defaults and use ASP.NET Core
features like IApplicationBuilder
, I believe that you are planning to run the service over some kind of web server. Is this correct?
If so, besides the other good suggestions, I have another one, which is to keep using an ASP.NET Core
app - obviously enabling the usage of the Startup
almost as is (with ConfigureServices
and Configure
methods) and perhaps most of your previous app.
To do so, in your Worker csproj
, you could replace <Project Sdk="Microsoft.NET.Sdk.Worker">
by <Project Sdk="Microsoft.NET.Sdk.Web">
.
Then, you can configure your CreateHostBuilder
such as:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(
webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
Please note that I removed UseWindowsService()
on purpose, since I am describing a case of using Worker services
and not specifically Windows services
.
Now you can keep using your Startup
class, adding the registration of your background service(s):
public class Startup
{
public Startup(IConfiguration configuration)
{
// ...
}
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddHostedService<Worker>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...
}
}
Hope this helps :) However, if you specifically want to develop Windows services
rather than Worker services
, please let us know.
In this case, we keep having an ASP.NET Core WebApp/WebAPI with all its capabilities. We just added background services to it :)