-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: Add IHostApplicationBuilder interface #85486
Comments
Tagging subscribers to this area: @dotnet/area-extensions-hosting Issue DetailsBackground and motivationIn .NET 6, ASP.NET added a The problem is these two hosting APIs have the same members (mostly), but don't have a common base abstraction that libraries can add extension methods to. In the previous, callback API To enable this, we should add a general abstraction to these hosting builder APIs. See the conversations at:
API Proposalnamespace Microsoft.Extensions.Hosting;
public interface IHostApplicationBuilder
{
IDictionary<object, object> Properties { get; }
IConfigurationBuilder Configuration { get; } // can't be ConfigurationManager since that is in MS.Ext.Configuration and Hosting.Abstractions references Configuration.Abstractions. So need to pick between IConfiguration and IConfigurationBuilder
IHostEnvironment Environment { get; }
ILoggingBuilder Logging { get; }
IServiceCollection Services { get; }
IHost Build(); // See Note below on `Build()`
void ConfigureContainer<TContainerBuilder>(IServiceProviderFactory<TContainerBuilder>factory, Action<TContainerBuilder>? configure = null) where TContainerBuilder: notnull;
} Note on Build()If we wanted to make this API work for all ApplicationBuilders like MauiAppBuilder and WebAssemblyHostBuilder, we would need to think about
API UsageUsing an existing extension method on public static class HostBuilderExtensions
{
public static IHostBuilder AddSteeltoe(this IHostBuilder hostBuilder, IEnumerable<string> exclusions = null, ILoggerFactory loggerFactory = null)
{
...
hostBuilder.Properties[LoggerName] = logger;
hostBuilder.Configuration.AddSteeltoeConfigServer();
hostBuilder.Services.AddMongoClient()
}
} Alternative DesignsWe could make RisksN/A
|
We have to fix the Configuration API to allow reading it. Maybe we need an interface for the ConfigurationManager (this is why interfaces are great 😄). |
How do you feel about 2 properties? public interface IHostApplicationBuilder
{
IConfiguration Configuration { get; }
IConfigurationBuilder ConfigurationBuilder { get; } ? |
Doesn't feel good, but it's an option. |
Updated the proposed API to include a new |
cc @dotnet/area-extensions-configuration as well, since this proposal spans both Hosting and Configuration. |
Who is planning on driving and implementing this? |
The majority of libraries can get by just extending I was able to update If you extend just We could consider adding a similar runtime/src/libraries/Microsoft.Extensions.Hosting/src/HostBuilder.cs Lines 181 to 191 in 87189ec
runtime/src/libraries/Microsoft.Extensions.Hosting/src/HostApplicationBuilder.cs Lines 307 to 314 in 87189ec
|
Agreed. That is what I found most libraries doing. Only a few, bigger libraries actually needed to extend https://grep.app/search?q=this%20IHostBuilder There are quite a few of cases I found that are just using
I am not in favor of doing this. I think we need to break away from the old, callback approach. My reasoning is in the |
Let's push forward with @eerhardt 's proposal. |
I can drive it in .NET 8. |
So the problem statement here is that existing libraries which extend Looks like we'd need to ask all those folks who have already implemented extensions to |
I have logged a few issues on code that I found extending IHostBuilder to make extension methods on IServiceCollection.
https://grep.app/search?q=this%20HostApplicationBuilder didn't find anyone trying to add an extension for HostApplicationBuilder. https://grep.app/search?q=this%20WebApplicationBuilder just finds regular apps defining their own extension methods. Outside of SteelToeOSS, I didn't find any reusable libraries extending WebApplicationBuilder. Which makes sense - reusable libraries don't want to depend directly on ASP.NET.
I'm not sure that analyzer would be worth the effort. It would also cause false positives in the case where I am just creating an extension method in my own app that uses IHostBuilder.
There is a bit of conflation of terms here. "Minimal APIs" mostly means being able to use After dotnet/aspnetcore#47720, we no longer have any templates in .NET 8 that use the "old Hosting" APIs (i.e. |
So how are we thinking about these in relation to the old callback APIs - both equal - or are the callback APIs now legacy? |
In my mind, the callback APIs are not going to get anymore improvements. Any new scenarios will only be using the inline Hosting APIs. So the callback APIs are effectively legacy. |
This is a tough question to answer, but we're attempting to move to this new model as it solves a couple of problems we have with the callback model and is a simpler API. That said, there are a different set of tradeoffs this model introduces over the callback model we had before (ones that we've discovered while having this). That said, it's the model we're trying to move forward with. |
Marking as ready for review in order to get this into .NET 8. |
Do you have a link for that proposal? This issue is the only one that comes up when I search this repo for IMetricsBuilder. Did you mean |
Part of that was that we know of new things that will be on these builders. Not saying it will be an abstract base class (you know how much I like those!) but we do need to evolve this API. |
We've established using DIMs in Microsoft.Extensions.* for |
I love it! |
I have my working draft here: https://gist.github.com/noahfalk/32bb919907c972ac06ac128bc767d48d#integration-with-hosting-apis I've never worked in the hosting APIs before so the current design follows the philosophy "duplicate whatever ILoggingBuilder did". Feedback is welcome if you think there is something we should be doing differently. |
namespace Microsoft.Extensions.Hosting;
public interface IHostApplicationBuilder
{
IDictionary<object, object> Properties { get; }
IConfigurationManager Configuration { get; }
IHostEnvironment Environment { get; }
ILoggingBuilder Logging { get; }
IServiceCollection Services { get; }
void ConfigureContainer<TContainerBuilder>(IServiceProviderFactory<TContainerBuilder>factory, Action<TContainerBuilder>? configure = null) where TContainerBuilder: notnull;
}
-public sealed class HostApplicationBuilder {}
+public sealed class HostApplicationBuilder : IHostApplicationBuilder {} namespace Microsoft.Extensions.Configuration;
public interface IConfigurationManager : IConfiguration, IConfigurationBuilder
{
}
-public sealed class ConfigurationManager : IConfigurationBuilder, IConfigurationRoot, IDisposable {}
+public sealed class ConfigurationManager : IConfigurationBuilder, IConfigurationRoot, IDisposable, IConfigurationManager {} |
- Move ILoggingBuilder from MS.Ext.Logging to MS.Ext.Logging.Abstractions so IHostApplicationBuilder can reference it. - Add IConfigurationManager and implement it in ConfigurationManager. - Add CompatiibilitySuppressions. These errors are caused by ILoggingBuilder being moved to Logging.Abstractions, and ApiCompat not respecting TypeForwardedTo attributes. Fix dotnet#85486
* Add IHostApplicationBuilder and implement it in HostApplicationBuilder. - Move ILoggingBuilder from MS.Ext.Logging to MS.Ext.Logging.Abstractions so IHostApplicationBuilder can reference it. - Add IConfigurationManager and implement it in ConfigurationManager. - Add CompatiibilitySuppressions. These errors are caused by ILoggingBuilder being moved to Logging.Abstractions, and ApiCompat not respecting TypeForwardedTo attributes. Fix #85486
Background and motivation
In .NET 6, ASP.NET added a
WebApplicationBuilder
"minimal hosting" API. This was a new, non-callback approach to theHostBuilder
Generic Host API. In .NET 7, Extensions.Hosting added a similar "generic host" API that followed the same non-callback API design.The problem is these two hosting APIs have the same members (mostly), but don't have a common base abstraction that libraries can add extension methods to. In the previous, callback API
IHostBuilder
was the interface libraries could extend and add their library-specific DI services, etc. to.To enable this, we should add a general abstraction to these hosting builder APIs.
See the conversations at:
Host.CreateApplicationBuilder
aspnetcore#47720 (comment)API Proposal
Note on Build()
If we wanted to make this API work for all ApplicationBuilders like MauiAppBuilder and WebAssemblyHostBuilder, we would need to think about
IHost Build()
. Those 2 app models follow this same ApplicationBuilder pattern, but the things they build don't implementIHost
. Options here are:Build()
in the interface. But the name of the interface is "Builder", so it doesn't feel right to not have aBuild
method.IHost
, they would throw NotSupported for this method. This is my recommendation.API Usage
Using an existing extension method on
IHostBuilder
as an example, a new extension method could be written like:Alternative Designs
We could make
WebApplicationBuilder
andHostApplicationBuilder
explicitly implementIHostBuilder
, but this breaks the API design of making the hosting code minimal, and running inline. It would cause a lot of confusion on when services, config, etc gets added in which order. For this reason, we don't want to keep using theIHostBuilder
interface in new code.Risks
N/A
The text was updated successfully, but these errors were encountered: