|
| 1 | +--- |
| 2 | +title: .NET Generic Host in ASP.NET Framework |
| 3 | +description: How to take advantage of the .NET generic hosting pattern in ASP.NET Framework applications |
| 4 | +ai-usage: ai-assisted |
| 5 | +author: twsouthwick |
| 6 | +ms.author: tasou |
| 7 | +monikerRange: '>= aspnetcore-6.0' |
| 8 | +ms.date: 11/10/2025 |
| 9 | +ms.topic: article |
| 10 | +uid: migration/fx-to-core/areas/hosting |
| 11 | +--- |
| 12 | + |
| 13 | +# ASP.NET Framework HttpApplicationHost |
| 14 | + |
| 15 | +The System.Web adapters library enables ASP.NET Framework applications to use the .NET generic host pattern, bringing modern application infrastructure capabilities to traditional ASP.NET Framework projects. This approach provides access to dependency injection, logging, configuration, and other services that are standard in modern .NET applications, while maintaining compatibility with existing ASP.NET Framework code. |
| 16 | + |
| 17 | +## Why use the host pattern |
| 18 | + |
| 19 | +Adopting the generic host pattern in ASP.NET Framework applications provides several key benefits: |
| 20 | + |
| 21 | +* **Dependency Injection**: Access to the built-in dependency injection container used in modern .NET, enabling better testability, maintainability, and separation of concerns |
| 22 | +* **Unified Logging**: Integration with `Microsoft.Extensions.Logging`, providing a consistent logging experience across your application and access to various logging providers |
| 23 | +* **Modern Configuration**: Use the configuration system from modern .NET, including support for JSON files, environment variables, user secrets, and other configuration sources |
| 24 | +* **Migration Path**: Prepare your codebase for migration to ASP.NET Core by adopting modern patterns incrementally while maintaining your existing ASP.NET Framework application |
| 25 | +* **Service Defaults**: Leverage service defaults and standardized application infrastructure patterns commonly used in modern .NET applications |
| 26 | + |
| 27 | +## Setting up the generic host |
| 28 | + |
| 29 | +To configure the generic host pattern in an ASP.NET Framework application, register the host in the `Application_Start` method of your `Global.asax.cs` file: |
| 30 | + |
| 31 | +```csharp |
| 32 | +using System.Web; |
| 33 | +using Microsoft.AspNetCore.SystemWebAdapters.Hosting; |
| 34 | +using Microsoft.Extensions.Hosting; |
| 35 | + |
| 36 | +namespace MvcApp |
| 37 | +{ |
| 38 | + public class MvcApplication : HttpApplication |
| 39 | + { |
| 40 | + protected void Application_Start() |
| 41 | + { |
| 42 | + HttpApplicationHost.RegisterHost(builder => |
| 43 | + { |
| 44 | + builder.AddServiceDefaults(); |
| 45 | + builder.AddSystemWebDependencyInjection(); |
| 46 | + builder.AddSystemWebAdapters(); |
| 47 | + }); |
| 48 | + |
| 49 | + // Existing ASP.NET Framework configuration |
| 50 | + AreaRegistration.RegisterAllAreas(); |
| 51 | + GlobalConfiguration.Configure(WebApiConfig.Register); |
| 52 | + FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); |
| 53 | + RouteConfig.RegisterRoutes(RouteTable.Routes); |
| 54 | + BundleConfig.RegisterBundles(BundleTable.Bundles); |
| 55 | + } |
| 56 | + } |
| 57 | +} |
| 58 | +``` |
| 59 | + |
| 60 | +The `HttpApplicationHost.RegisterHost` method configures a generic host that runs alongside your ASP.NET Framework application. The host builder accepts configuration through extension methods that add various capabilities. |
| 61 | + |
| 62 | +## Dependency injection |
| 63 | + |
| 64 | +> [!NOTE] |
| 65 | +> This currently is in a preview version of the adapters. You must be using 2.2.0-preview1.25554.5 or greater to use this feature. |
| 66 | +
|
| 67 | +The `AddSystemWebDependencyInjection` method enables dependency injection throughout your ASP.NET Framework application. Services registered with the generic host's service collection become available to controllers, handlers, and other components. |
| 68 | + |
| 69 | +This extension method is an internal method that will be source generated depending on what you have referenced. The following frameworks are supported: |
| 70 | + |
| 71 | +- WebForms and handlers using the <xref:System.Web.HttpRuntime.WebObjectActivator> |
| 72 | +- ASP.NET MVC using <xref:System.Web.Mvc.DependencyResolver> |
| 73 | +- ASP.NET WebApi using [DependencyResolver](/previous-versions/aspnet/hh969140(v=vs.108)) |
| 74 | + |
| 75 | +### Registering services |
| 76 | + |
| 77 | +Register services with the dependency injection container by accessing the `Services` property on the host builder: |
| 78 | + |
| 79 | +```csharp |
| 80 | +HttpApplicationHost.RegisterHost(builder => |
| 81 | +{ |
| 82 | + builder.AddSystemWebDependencyInjection(); |
| 83 | + builder.AddSystemWebAdapters(); |
| 84 | + |
| 85 | + builder.Services.AddScoped<IMyService, MyService>(); |
| 86 | + builder.Services.AddSingleton<IDataRepository, DataRepository>(); |
| 87 | +}); |
| 88 | +``` |
| 89 | + |
| 90 | +For details on how to customize the dependency injection system, including replacing the service container, see the full documentation: <xref:fundamentals/dependency-injection>. |
| 91 | + |
| 92 | +If you are currently overriding the dependency injection hooks in the ASP.NET Framework, you will need to update to the current pattern for your dependency injection and remove the existing integrations for WebForms/MVC4/WebAPI. |
| 93 | + |
| 94 | +### Consuming services |
| 95 | + |
| 96 | +Once registered, services can be injected into MVC controllers, Web API controllers, and other components that support dependency injection: |
| 97 | + |
| 98 | +```csharp |
| 99 | +public class HomeController : Controller |
| 100 | +{ |
| 101 | + private readonly IMyService _myService; |
| 102 | + private readonly ILogger<HomeController> _logger; |
| 103 | + |
| 104 | + public HomeController(IMyService myService, ILogger<HomeController> logger) |
| 105 | + { |
| 106 | + _myService = myService; |
| 107 | + _logger = logger; |
| 108 | + } |
| 109 | + |
| 110 | + public ActionResult Index() |
| 111 | + { |
| 112 | + _logger.LogInformation("Loading home page"); |
| 113 | + var data = _myService.GetData(); |
| 114 | + return View(data); |
| 115 | + } |
| 116 | +} |
| 117 | +``` |
| 118 | + |
| 119 | +Within a request, a scoped set of services may be retrieved by a special extension method: |
| 120 | + |
| 121 | +```csharp |
| 122 | +var myService = HttpContext.Current.GetRequestServices().GetService(typeof(ISomeType)); |
| 123 | +``` |
| 124 | + |
| 125 | +> [!WARNING] |
| 126 | +> <xref:System.Web.HttpContext> implements <xref:System.IServiceProvider> so you may see extension methods to get services from it. However, it is not implemented in a way to retrieve any useful services from a registered container. You will see an error if you attempt to use it and you should instead use the `GetRequestServices()` extension method first. |
| 127 | +
|
| 128 | +## Logging |
| 129 | + |
| 130 | +The generic host integrates `Microsoft.Extensions.Logging`, providing a modern logging infrastructure for your ASP.NET Framework application. |
| 131 | + |
| 132 | +### Using loggers |
| 133 | + |
| 134 | +Inject `ILogger<T>` into your classes to log messages: |
| 135 | + |
| 136 | +```csharp |
| 137 | +public class OrderService : IOrderService |
| 138 | +{ |
| 139 | + private readonly ILogger<OrderService> _logger; |
| 140 | + |
| 141 | + public OrderService(ILogger<OrderService> logger) |
| 142 | + { |
| 143 | + _logger = logger; |
| 144 | + } |
| 145 | + |
| 146 | + public void ProcessOrder(int orderId) |
| 147 | + { |
| 148 | + _logger.LogInformation("Processing order {OrderId}", orderId); |
| 149 | + |
| 150 | + try |
| 151 | + { |
| 152 | + // Process order logic |
| 153 | + _logger.LogDebug("Order {OrderId} processed successfully", orderId); |
| 154 | + } |
| 155 | + catch (Exception ex) |
| 156 | + { |
| 157 | + _logger.LogError(ex, "Error processing order {OrderId}", orderId); |
| 158 | + throw; |
| 159 | + } |
| 160 | + } |
| 161 | +} |
| 162 | +``` |
| 163 | + |
| 164 | +For details on customizing and using logging, including integrating with your own providers, see <xref:fundamentals/logging/index>. |
| 165 | + |
| 166 | +## Configuration |
| 167 | + |
| 168 | +The generic host supports the modern .NET configuration system, including JSON files, environment variables, and other configuration sources. By default, the `HttpApplicationHost` uses standard configuration patterns (such as `appsettings.json` and `appsettings.{Environment}.json`), and automatically includes values from <xref:System.Configuration.ConfigurationManager.AppSettings> and <xref:System.Configuration.ConfigurationManager.ConnectionStrings> for compatibility with existing ASP.NET Framework applications. |
| 169 | + |
| 170 | +### Accessing configuration |
| 171 | + |
| 172 | +Inject `IConfiguration` to access configuration values: |
| 173 | + |
| 174 | +```csharp |
| 175 | +public class EmailService : IEmailService |
| 176 | +{ |
| 177 | + private readonly string _smtpServer; |
| 178 | + private readonly ILogger<EmailService> _logger; |
| 179 | + |
| 180 | + public EmailService(IConfiguration configuration, ILogger<EmailService> logger) |
| 181 | + { |
| 182 | + _smtpServer = configuration["Email:SmtpServer"]; |
| 183 | + _logger = logger; |
| 184 | + } |
| 185 | + |
| 186 | + public void SendEmail(string to, string subject, string body) |
| 187 | + { |
| 188 | + _logger.LogInformation("Sending email to {Recipient} via {SmtpServer}", to, _smtpServer); |
| 189 | + // Email sending logic |
| 190 | + } |
| 191 | +} |
| 192 | +``` |
| 193 | + |
| 194 | +For code that can't use dependency injection, use the static `AppConfiguration` helper class to access configuration values: |
| 195 | + |
| 196 | +```csharp |
| 197 | +using Microsoft.AspNetCore.SystemWebAdapters; |
| 198 | + |
| 199 | +var configValue = AppConfiguration.GetSetting("SomeSettings"); |
| 200 | +var connStr = AppConfiguration.GetConnectionString("connection-string-name"); |
| 201 | +``` |
| 202 | + |
| 203 | +This will work on both ASP.NET Core and ASP.NET Framework applications that are referencing `Microsoft.AspNetCore.SystemWebAdapters` and will provide access to the current `IConfiguration`. |
| 204 | + |
| 205 | +### Using options pattern |
| 206 | + |
| 207 | +The options pattern provides strongly-typed access to configuration sections: |
| 208 | + |
| 209 | +```csharp |
| 210 | +public class EmailSettings |
| 211 | +{ |
| 212 | + public string SmtpServer { get; set; } |
| 213 | + public int Port { get; set; } |
| 214 | + public string Username { get; set; } |
| 215 | +} |
| 216 | + |
| 217 | +// Register options |
| 218 | +HttpApplicationHost.RegisterHost(builder => |
| 219 | +{ |
| 220 | + builder.Services.Configure<EmailSettings>( |
| 221 | + builder.Configuration.GetSection("Email")); |
| 222 | + |
| 223 | + builder.AddSystemWebDependencyInjection(); |
| 224 | + builder.AddSystemWebAdapters(); |
| 225 | +}); |
| 226 | + |
| 227 | +// Consume options |
| 228 | +public class EmailService : IEmailService |
| 229 | +{ |
| 230 | + private readonly EmailSettings _settings; |
| 231 | + private readonly ILogger<EmailService> _logger; |
| 232 | + |
| 233 | + public EmailService(IOptions<EmailSettings> options, ILogger<EmailService> logger) |
| 234 | + { |
| 235 | + _settings = options.Value; |
| 236 | + _logger = logger; |
| 237 | + } |
| 238 | +} |
| 239 | +``` |
| 240 | + |
| 241 | +For advanced configuration scenarios, including custom configuration sources and environment-specific settings, see <xref:fundamentals/configuration/index>. |
| 242 | + |
| 243 | +## Migration strategies |
| 244 | + |
| 245 | +Completely converting to the generic host pattern may not be needed for smaller projects, but can make migration much easier for larger projects. If you have successfully converted to using this, then you can swap the `HttpApplicationHost` usage for the `WebApplication` in ASP.NET Core. |
| 246 | + |
| 247 | +While migrating to this setup, small incremental changes will help ensure a successful conversion. A recommended order to use for migrating here would be the following: |
| 248 | + |
| 249 | +1. Add an initial host registration: |
| 250 | + ```csharp |
| 251 | + HttpApplicationHost.RegisterHost(builder => |
| 252 | + { |
| 253 | + }); |
| 254 | + ``` |
| 255 | +1. Update to use Microsoft Extensions dependency injection: |
| 256 | + ```csharp |
| 257 | + HttpApplicationHost.RegisterHost(builder => |
| 258 | + { |
| 259 | + builder.AddSystemWebDependencyInjection(); |
| 260 | + }); |
| 261 | + ``` |
| 262 | + |
| 263 | + While doing this, you may need to adapt your current containers according to their own documentation for integrating in with the Microsoft Extensions dependency injection |
| 264 | +1. Identify your logging system and integrate it into the Microsoft Extension logging infrastructure. Decide if you want to continue using the logger types from your existing system or migrating to the `ILogger<>` types the HttpApplicationHost will provide. |
| 265 | +1. Replace all calls to <xref:System.Configuration.ConfigurationManager.AppSettings> and <xref:System.Configuration.ConfigurationManager.ConnectionStrings> with the new equivalent `AppConfiguration` call. You must be referencing `Microsoft.AspNetCore.SystemWebAdapters` in the project where you want to do this. |
| 266 | +1. Start using the options pattern to convert configuration into POCO that can be passed to consuming services using the integrated DI system |
| 267 | +1. Move your settings from `web.config` to `appsettings.json` |
| 268 | + |
| 269 | +## Additional resources |
| 270 | + |
| 271 | +* <xref:fundamentals/host/generic-host> |
| 272 | +* <xref:fundamentals/dependency-injection> |
| 273 | +* <xref:fundamentals/logging/index> |
| 274 | +* <xref:fundamentals/configuration/index> |
0 commit comments