- This adds an implementation of IWebHostBuilder as a facade over the IHostBuilder.
This removes the 2 container issue by executing the Startup.ConfigureServies and Startup.ConfigureContainer inline as part of building the IHostBuilder.
- The implementation is highly compatible implementation since it exposes the same IWebHostBuilder interface.
Existing extensions mostly work.
- There are some caveats with this approach.
- Injecting services into Startup is not extremely constrained to the
services availble on HostBuilderContext. This includes the IHostingEnvironment
and the IConfiguration.
- IStartup is broken when using this pattern because it isn't composable.
- The IStartupConfigureServicesFilter and IStartupConfigureContainer The before
and after filters added in 2.1 are also broken because there's a single container (it could maybe be fixed by downcasting and doing something specific on the GenericHostBuilder instance).
- Calling into IWebHostBuilder.Build will throw a NotSupportedException since
this implementation is just a facade over the IHostBuilder.
- Use the IServiceProviderFactory<IServiceCollection>
- Assert creation and disposal service providers
- Updated the tests to verify that service providers are created and disposed
- Called CreateBuilder even in the default case in case the service collection is modified as part of it.
- The goal here is to enable components that use hosting abstractions to use
the web host. It lets us start to decouple components from the web host abstractions
where possible while not breaking any existing components. This will allow things
to work in both the generic host and the web host. The one snafu is the WebHostBuilderContext
which has an IHostingEnvironment typed as the AspNetCore.Abstractions type.
- Updated tests.
#1218
* Add BackgroundService, a base class for long running HostedServices
- Today the IHostedService pattern is a StartAsync/StopAsync pattern. Neither of these
methods are supposed to return a long running task that represents an execution. If
you wanted to have some logic run on a timer every 5 minutes, it's unnatural to do so
with simple async idioms. This base class implements IHostedService and exposes
a pattern where a long running async Task can be returned.
- The token passed into ExecuteAsync represents the lifetime of the execution.
- StartAsync and StopAsync were made virtual to allow the derived type to
indicate Start failures.
- Added tests
* Create a sources package to encode the convention followed in our templates to create a WebHost.
* Add an extension method to setup the content root relative to the solution folder.
* Add a factory method to create a WebHostBuilder based on the pattern followed in our template.
* Add IStartupConfigureServicesFilter to wrap ConfigureServices.
* Add IStartupConfigureContainerFilter<TContainerBuilder> to wrap
ConfigureContainer.
* Make StartupLoader build a thunk for configure services that
resolves all instances of IStartupConfigureServicesFilter and
IStartupConfigureContainerFilter<TContainerBuilder> and wraps
invocations to ConfigureServices and ConfigureContainer respectively.
* Refactor building the ConfigureServices callback into a private
builder class due to the increased complexity in the process.