@@ -212,16 +212,51 @@ protected override Assembly Load(AssemblyName assemblyName)
212
212
// If this is a runtime restricted assembly, load it based on unification rules
213
213
if ( TryGetRuntimeAssembly ( assemblyName , out ScriptRuntimeAssembly scriptRuntimeAssembly ) )
214
214
{
215
- assembly = LoadRuntimeAssembly ( assemblyName , scriptRuntimeAssembly ) ;
216
-
217
- // If the policy evaluation failed because the AssemblyName was adjusted due to
218
- // deps.json, we cannot allow the Default context to load it. Instead, load directly.
219
- if ( assembly == null && isNameAdjusted )
215
+ // There are several possible scenarios:
216
+ // 1. The assembly was found and the policy evaluator succeeded.
217
+ // - Return the assembly.
218
+ //
219
+ // 2. The assembly was not found (meaning the policy evaluator wasn't able to run).
220
+ // - Return null as there's not much else we can do. This will fail and come back to this context
221
+ // through the fallback logic for another attempt. This is likely an error case so let it fail.
222
+ //
223
+ // 3. The assembly was found but the policy evaluator failed.
224
+ // a. We did not adjust the requested assembly name via the deps file.
225
+ // - This means that the DefaultLoadContext is looking for the correct version. Return null and let
226
+ // it handle the load attempt.
227
+ // b. We adjusted the requested assembly name via the deps file. If we return null the DefaultLoadContext would attempt to
228
+ // load the original assembly version, which may be incorrect if we had to adjust it forward past the runtime's version.
229
+ // i. The adjusted assembly name is higher than the runtime's version.
230
+ // - Do not trust the DefaultLoadContext to handle this as it may resolve to the runtime's assembly. Instead,
231
+ // call LoadCore() to ensure the adjusted assembly is loaded.
232
+ // ii. The adjusted assembly name is still lower than or equal to the runtime's version (this likely means
233
+ // a lower major version).
234
+ // - Return null and let the DefaultLoadContext handle it. It may come back here due to fallback logic, but
235
+ // ultimately it will unify on the runtime version.
236
+
237
+ if ( TryLoadRuntimeAssembly ( assemblyName , scriptRuntimeAssembly , out assembly ) )
220
238
{
221
- assembly = LoadCore ( assemblyName ) ;
239
+ // Scenarios 1 and 2(a).
240
+ return assembly ;
222
241
}
242
+ else
243
+ {
244
+ if ( assembly == null || ! isNameAdjusted )
245
+ {
246
+ // Scenario 2 and 3(a).
247
+ return null ;
248
+ }
223
249
224
- return assembly ;
250
+ AssemblyName runtimeAssemblyName = AssemblyNameCache . GetName ( assembly ) ;
251
+ if ( assemblyName . Version > runtimeAssemblyName . Version )
252
+ {
253
+ // Scenario 3(b)(i).
254
+ return LoadCore ( assemblyName ) ;
255
+ }
256
+
257
+ // Scenario 3(b)(ii).
258
+ return null ;
259
+ }
225
260
}
226
261
227
262
// If the assembly being requested matches a host assembly, we'll use
@@ -257,26 +292,31 @@ private bool TryAdjustRuntimeAssemblyFromDepsFile(AssemblyName assemblyName, out
257
292
return false ;
258
293
}
259
294
260
- private Assembly LoadRuntimeAssembly ( AssemblyName assemblyName , ScriptRuntimeAssembly scriptRuntimeAssembly )
295
+ /// <summary>
296
+ /// Loads the runtime's version of this assembly and runs it through the appropriate policy evaluator.
297
+ /// </summary>
298
+ /// <param name="assemblyName">The assembly name to load.</param>
299
+ /// <param name="scriptRuntimeAssembly">The policy evaluator details.</param>
300
+ /// <param name="runtimeAssembly">The runtime's assembly.</param>
301
+ /// <returns>true if the policy evaluation succeeded, otherwise, false.</returns>
302
+ private bool TryLoadRuntimeAssembly ( AssemblyName assemblyName , ScriptRuntimeAssembly scriptRuntimeAssembly , out Assembly runtimeAssembly )
261
303
{
262
304
// If this is a private runtime assembly, return function dependency
263
305
if ( string . Equals ( scriptRuntimeAssembly . ResolutionPolicy , PrivateDependencyResolutionPolicy ) )
264
306
{
265
- return LoadCore ( assemblyName ) ;
307
+ runtimeAssembly = LoadCore ( assemblyName ) ;
308
+ return true ;
266
309
}
267
310
268
311
// Attempt to load the runtime version of the assembly based on the unification policy evaluation result.
269
- if ( TryLoadHostEnvironmentAssembly ( assemblyName , allowPartialNameMatch : true , out Assembly assembly ) )
312
+ if ( TryLoadHostEnvironmentAssembly ( assemblyName , allowPartialNameMatch : true , out runtimeAssembly ) )
270
313
{
271
314
var policyEvaluator = GetResolutionPolicyEvaluator ( scriptRuntimeAssembly . ResolutionPolicy ) ;
272
-
273
- if ( policyEvaluator . Invoke ( assemblyName , assembly ) )
274
- {
275
- return assembly ;
276
- }
315
+ return policyEvaluator . Invoke ( assemblyName , runtimeAssembly ) ;
277
316
}
278
317
279
- return null ;
318
+ runtimeAssembly = null ;
319
+ return false ;
280
320
}
281
321
282
322
private bool TryLoadDepsDependency ( AssemblyName assemblyName , out Assembly assembly )
0 commit comments