@@ -62,7 +62,7 @@ public IServiceProvider CreateServiceProvider(IServiceCollection services)
62
62
throw new HostInitializationException ( "Invalid host services detected." , ex ) ;
63
63
}
64
64
65
- ShimBreakingChange ( services ) ;
65
+ ShimBreakingChanges ( services , _logger ) ;
66
66
67
67
// Start from the root (web app level) as a base
68
68
var jobHostServices = _rootProvider . CreateChildContainer ( _rootServices ) ;
@@ -76,12 +76,71 @@ public IServiceProvider CreateServiceProvider(IServiceCollection services)
76
76
return jobHostServices . BuildServiceProvider ( ) ;
77
77
}
78
78
79
+ private static void ShimBreakingChanges ( IServiceCollection services , ILogger logger )
80
+ {
81
+ ShimActivatorUtilitiesConstructorAttributeTypes ( services , logger ) ;
82
+ ShimLegacyNetWorkerMetadataProvider ( services , logger ) ;
83
+ }
84
+
85
+ /// <summary>
86
+ /// Versions 1.3.0 and older of Microsoft.Azure.Functions.Worker.Sdk register a type with a constructor that
87
+ /// takes a string parameter. This worked with DryIoc, but not with the new DI container.
88
+ /// Shimming those types to provide backwards compatibility, but this should be removed in the future.
89
+ /// </summary>
90
+ /// <param name="services">The <see cref="ServiceCollection"/> to inspect and modify.</param>
91
+ /// <param name="logger">The <see cref="ILogger"/> to log information.</param>
92
+ private static void ShimLegacyNetWorkerMetadataProvider ( IServiceCollection services , ILogger logger )
93
+ {
94
+ const string functionProviderTypeName = "Microsoft.Azure.WebJobs.Extensions.FunctionMetadataLoader.JsonFunctionProvider, Microsoft.Azure.WebJobs.Extensions.FunctionMetadataLoader, Version=1.0.0.0, Culture=neutral, PublicKeyToken=551316b6919f366c" ;
95
+ const string jsonReaderTypeName = "Microsoft.Azure.WebJobs.Extensions.FunctionMetadataLoader.FunctionMetadataJsonReader, Microsoft.Azure.WebJobs.Extensions.FunctionMetadataLoader, Version=1.0.0.0, Culture=neutral, PublicKeyToken=551316b6919f366c" ;
96
+
97
+ Type functionProviderType = Type . GetType ( functionProviderTypeName ) ;
98
+ if ( functionProviderType is null )
99
+ {
100
+ return ;
101
+ }
102
+
103
+ Type jsonReaderType = Type . GetType ( jsonReaderTypeName ) ;
104
+ var constructor = functionProviderType . GetConstructor ( [ jsonReaderType , typeof ( string ) ] ) ;
105
+ if ( constructor is null )
106
+ {
107
+ return ;
108
+ }
109
+
110
+ ServiceDescriptor descriptorToShim = null ;
111
+ foreach ( ServiceDescriptor descriptor in services )
112
+ {
113
+ if ( descriptor . ImplementationType == functionProviderType )
114
+ {
115
+ logger . LogInformation ( "Shimming .NET Worker Function Provider constructor for {ImplementationType}." , descriptor . ImplementationType ) ;
116
+ descriptorToShim = descriptor ;
117
+ break ;
118
+ }
119
+ }
120
+
121
+ if ( descriptorToShim is not null )
122
+ {
123
+ var newDescriptor = ServiceDescriptor . Describe (
124
+ descriptorToShim . ServiceType ,
125
+ sp =>
126
+ {
127
+ var jsonReader = sp . GetRequiredService ( jsonReaderType ) ;
128
+ return constructor . Invoke ( [ jsonReader , null ] ) ;
129
+ } ,
130
+ descriptorToShim . Lifetime ) ;
131
+
132
+ services . Remove ( descriptorToShim ) ;
133
+ services . Add ( newDescriptor ) ;
134
+ }
135
+ }
136
+
79
137
/// <summary>
80
138
/// .NET 8 has a breaking change regarding <see cref="ActivatorUtilitiesConstructorAttribute"/> no longer functioning as expected.
81
139
/// We have some known extension types which are impacted by this. To avoid a regression, we are manually shimming those types.
82
140
/// </summary>
83
141
/// <param name="services">The service collection.</param>
84
- private void ShimBreakingChange ( IServiceCollection services )
142
+ /// <param name="logger">The <see cref="ILogger"/> to log information.</param>
143
+ private static void ShimActivatorUtilitiesConstructorAttributeTypes ( IServiceCollection services , ILogger logger )
85
144
{
86
145
Dictionary < ServiceDescriptor , ServiceDescriptor > toReplace = null ;
87
146
static bool HasPreferredCtor ( Type type )
@@ -105,7 +164,7 @@ bool TryCreateReplacement(ServiceDescriptor descriptor, out ServiceDescriptor re
105
164
return false ;
106
165
}
107
166
108
- _logger . LogInformation ( "Shimming DI constructor for {ImplementationType}." , descriptor . ImplementationType ) ;
167
+ logger . LogInformation ( "Shimming DI constructor for {ImplementationType}." , descriptor . ImplementationType ) ;
109
168
ObjectFactory factory = ActivatorUtilities . CreateFactory ( descriptor . ImplementationType , Type . EmptyTypes ) ;
110
169
111
170
replacement = ServiceDescriptor . Describe (
0 commit comments