1212using Microsoft . Extensions . Configuration ;
1313using Microsoft . Extensions . DependencyInjection ;
1414using Microsoft . Extensions . DependencyInjection . Extensions ;
15+ using Microsoft . Extensions . Options ;
1516
1617namespace Microsoft . AspNetCore . SystemWebAdapters ;
1718
@@ -24,41 +25,59 @@ public static void AddHostingRuntime(this IServiceCollection services)
2425 services . TryAddSingleton < IMapPathUtility , MapPathUtility > ( ) ;
2526 services . TryAddEnumerable ( ServiceDescriptor . Transient < IStartupFilter , HostingEnvironmentStartupFilter > ( ) ) ;
2627
27- services . AddOptions < SystemWebAdaptersOptions > ( )
28+ services . TryAddEnumerable ( ServiceDescriptor . Transient < IConfigureOptions < SystemWebAdaptersOptions > , OlderIISModuleSupport > ( ) ) ;
29+ services . TryAddEnumerable ( ServiceDescriptor . Transient < IConfigureOptions < SystemWebAdaptersOptions > , EnvironmentFeatureConfigureOptions > ( ) ) ;
30+ services . TryAddEnumerable ( ServiceDescriptor . Transient < IConfigureOptions < SystemWebAdaptersOptions > , DefaultAppPathConfigureOptions > ( ) ) ;
31+ }
2832
29- // This configures for anyone using older IIS modules that don't set the values (and to maintain behavior with the adapters <1.3)
30- . Configure ( options =>
33+ /// <summary>
34+ /// On .NET 8+, IIISEnvironmentFeature is available by default if running on IIS. We have an internal version
35+ /// we load at startup so that regardless of version and server this may be available (for example, in case some
36+ /// one wants to set the environment variables on a Kestrel hosted system to get the behavior)
37+ /// </summary>
38+ private sealed class EnvironmentFeatureConfigureOptions ( IServer server ) : IConfigureOptions < SystemWebAdaptersOptions >
39+ {
40+ public void Configure ( SystemWebAdaptersOptions options )
41+ {
42+ if ( server . Features . Get < IIISEnvironmentFeature > ( ) is { } feature )
3143 {
32- options . IsHosted = true ;
44+ options . ApplicationPhysicalPath = feature . ApplicationPhysicalPath ;
45+ options . ApplicationVirtualPath = feature . ApplicationVirtualPath ;
46+ options . ApplicationID = feature . ApplicationId ;
47+ options . SiteName = feature . SiteName ;
48+ }
49+ }
50+ }
3351
34- if ( NativeMethods . IsAspNetCoreModuleLoaded ( ) )
35- {
36- var config = NativeMethods . HttpGetApplicationProperties ( ) ;
52+ /// <summary>
53+ /// On ASP.NET Core this should be the same. We're doing it here rather than a PostConfigure because someone may want to set it up differently
54+ /// </summary>
55+ private sealed class DefaultAppPathConfigureOptions : IConfigureOptions < SystemWebAdaptersOptions >
56+ {
57+ public void Configure ( SystemWebAdaptersOptions options )
58+ {
59+ options . AppDomainAppPath = options . ApplicationPhysicalPath ;
60+ options . AppDomainAppVirtualPath = options . ApplicationVirtualPath ;
61+ }
62+ }
3763
38- options . ApplicationPhysicalPath = config . pwzFullApplicationPath ;
39- options . ApplicationVirtualPath = config . pwzVirtualApplicationPath ;
40- }
41- } )
64+ /// <summary>
65+ /// This configures for anyone using older IIS modules that don't set the values (and to maintain behavior with the adapters <1.3)
66+ /// </summary>
67+ private sealed class OlderIISModuleSupport : IConfigureOptions < SystemWebAdaptersOptions >
68+ {
69+ public void Configure ( SystemWebAdaptersOptions options )
70+ {
71+ options . IsHosted = true ;
4272
43- // On .NET 8+, IIISEnvironmentFeature is available by default if running on IIS. We have an internal version
44- // we load at startup so that regardless of version and server this may be available (for example, in case some
45- // one wants to set the environment variables on a Kestrel hosted system to get the behavior)
46- . Configure < IServer > ( ( options , server ) =>
73+ if ( NativeMethods . IsAspNetCoreModuleLoaded ( ) )
4774 {
48- if ( server . Features . Get < IIISEnvironmentFeature > ( ) is { } feature )
49- {
50- options . ApplicationPhysicalPath = feature . ApplicationPhysicalPath ;
51- options . ApplicationVirtualPath = feature . ApplicationVirtualPath ;
52- options . ApplicationID = feature . ApplicationId ;
53- options . SiteName = feature . SiteName ;
54- }
55- } )
56- . Configure ( options =>
57- {
58- // On ASP.NET Core this should be the same. We're doing it here rather than a PostConfigure because someone may want to set it up differently
59- options . AppDomainAppPath = options . ApplicationPhysicalPath ;
60- options . AppDomainAppVirtualPath = options . ApplicationVirtualPath ;
61- } ) ;
75+ var config = NativeMethods . HttpGetApplicationProperties ( ) ;
76+
77+ options . ApplicationPhysicalPath = config . pwzFullApplicationPath ;
78+ options . ApplicationVirtualPath = config . pwzVirtualApplicationPath ;
79+ }
80+ }
6281 }
6382
6483 private sealed class HostingEnvironmentStartupFilter : IStartupFilter
0 commit comments