@@ -27,98 +27,67 @@ internal sealed class RazorAnalyzerAssemblyResolver() : IAnalyzerAssemblyResolve
27
27
28
28
internal static readonly ImmutableArray < string > RazorAssemblyNames = [ RazorCompilerAssemblyName , RazorUtilsAssemblyName , ObjectPoolAssemblyName ] ;
29
29
30
- public Assembly ? Resolve ( AnalyzerAssemblyLoader loader , AssemblyName assemblyName , AssemblyLoadContext directoryContext , string directory )
31
- {
32
- if ( assemblyName . Name is not ( RazorCompilerAssemblyName or RazorUtilsAssemblyName or ObjectPoolAssemblyName ) )
33
- {
34
- return null ;
35
- }
36
-
37
- return Resolve ( loader . CompilerLoadContext , assemblyName , directory ) ;
38
- }
30
+ public Assembly ? Resolve ( AnalyzerAssemblyLoader loader , AssemblyName assemblyName , AssemblyLoadContext directoryContext , string directory ) =>
31
+ ResolveCore ( loader . CompilerLoadContext , assemblyName , directory ) ;
39
32
40
- public static Assembly ? ResolveRazorAssembly ( AssemblyName assemblyName , string rootDirectory )
41
- {
42
- var compilerLoadContext = AssemblyLoadContext . GetLoadContext ( typeof ( Microsoft . CodeAnalysis . Compilation ) . Assembly ) ! ;
43
- return Resolve ( compilerLoadContext , assemblyName , rootDirectory ) ;
44
- }
33
+ public static Assembly ? ResolveRazorAssembly ( AssemblyName assemblyName , string rootDirectory ) =>
34
+ ResolveCore (
35
+ AssemblyLoadContext . GetLoadContext ( typeof ( Microsoft . CodeAnalysis . Compilation ) . Assembly ) ! ,
36
+ assemblyName ,
37
+ rootDirectory ) ;
45
38
46
39
/// <summary>
47
40
/// This will resolve the razor generator assembly specified by <paramref name="assemblyName"/> in the specified
48
41
/// <paramref name="compilerLoadContext"/>.
49
- ///
50
- /// This will resolve _all_ of the known razor generator assemblies, not just the specified one. This is necessary
51
- /// because the compiler load context, unlike the directory load context, does not have a way to resolve dependencies.
52
- /// That means if we loaded Microsoft.CodeAnalysis.Razor.Compiler.dll and nothing else it's possible we'd eventually
53
- /// get an exception when it tried to access members in Microsoft.AspNetCore.Razor.Utilities.Shared.dll.
54
42
/// </summary>
55
- internal static Assembly ? Resolve ( AssemblyLoadContext compilerLoadContext , AssemblyName assemblyName , string directory )
43
+ internal static Assembly ? ResolveCore ( AssemblyLoadContext compilerLoadContext , AssemblyName assemblyName , string directory )
56
44
{
57
- Debug . Assert ( assemblyName . Name is not null ) ;
58
-
59
- var found = false ;
60
- Assembly ? resolvedAssembly = null ;
61
- foreach ( var name in RazorAssemblyNames )
45
+ if ( assemblyName . Name is not ( RazorCompilerAssemblyName or RazorUtilsAssemblyName or ObjectPoolAssemblyName ) )
62
46
{
63
- var assembly = resolve ( compilerLoadContext , new AssemblyName ( name ) , directory ) ;
64
- if ( name == assemblyName . Name )
65
- {
66
- found = true ;
67
- resolvedAssembly = assembly ;
68
- }
47
+ return null ;
69
48
}
70
49
71
- if ( ! found )
50
+ var assembly = compilerLoadContext . Assemblies . FirstOrDefault ( a => a . GetName ( ) . Name == assemblyName . Name ) ;
51
+ if ( assembly is not null )
72
52
{
73
- resolvedAssembly = resolve ( compilerLoadContext , assemblyName , directory ) ;
53
+ return assembly ;
74
54
}
75
55
76
- return resolvedAssembly ;
77
-
78
- static Assembly ? resolve ( AssemblyLoadContext compilerLoadContext , AssemblyName assemblyName , string directory )
56
+ var assemblyFileName = $ " { assemblyName . Name } .dll" ;
57
+ var assemblyPath = Path . Combine ( directory , assemblyFileName ) ;
58
+ if ( File . Exists ( assemblyPath ) )
79
59
{
80
- var assembly = compilerLoadContext . Assemblies . FirstOrDefault ( a => a . GetName ( ) . Name == assemblyName . Name ) ;
81
- if ( assembly is not null )
60
+ // https://github.com/dotnet/roslyn/issues/76868
61
+ //
62
+ // There is a subtle race condition in this logic as another thread could load the assembly inbetween
63
+ // the above calls and this one. Short term will just catch and grab the loaded assembly but longer
64
+ // term need to think about creating a dedicated AssemblyLoadContext for the razor assemblies
65
+ // which avoids this race condition.
66
+ try
82
67
{
83
- return assembly ;
68
+ assembly = compilerLoadContext . LoadFromAssemblyPath ( assemblyPath ) ;
84
69
}
85
-
86
- var assemblyFileName = $ "{ assemblyName . Name } .dll";
87
- var assemblyPath = Path . Combine ( directory , assemblyFileName ) ;
88
- if ( File . Exists ( assemblyPath ) )
70
+ catch
71
+ {
72
+ assembly = compilerLoadContext . Assemblies . Single ( a => a . GetName ( ) . Name == assemblyName . Name ) ;
73
+ }
74
+ }
75
+ else
76
+ {
77
+ // There are assemblies in the razor sdk generator directory that do not exist in the VS installation. That
78
+ // means when the paths are redirected, it's possible that the assembly is not found. In that case, we should
79
+ // load the assembly from the VS installation by querying through the compiler context.
80
+ try
89
81
{
90
- // https://github.com/dotnet/roslyn/issues/76868
91
- //
92
- // There is a subtle race condition in this logic as another thread could load the assembly inbetween
93
- // the above calls and this one. Short term will just catch and grab the loaded assembly but longer
94
- // term need to think about creating a dedicated AssemblyLoadContext for the razor assemblies
95
- // which avoids this race condition.
96
- try
97
- {
98
- assembly = compilerLoadContext . LoadFromAssemblyPath ( assemblyPath ) ;
99
- }
100
- catch
101
- {
102
- assembly = compilerLoadContext . Assemblies . Single ( a => a . GetName ( ) . Name == assemblyName . Name ) ;
103
- }
82
+ assembly = compilerLoadContext . LoadFromAssemblyName ( assemblyName ) ;
104
83
}
105
- else
84
+ catch ( FileNotFoundException )
106
85
{
107
- // There are assemblies in the razor sdk generator directory that do not exist in the VS installation. That
108
- // means when the paths are redirected, it's possible that the assembly is not found. In that case, we should
109
- // load the assembly from the VS installation by querying through the compiler context.
110
- try
111
- {
112
- assembly = compilerLoadContext . LoadFromAssemblyName ( assemblyName ) ;
113
- }
114
- catch ( FileNotFoundException )
115
- {
116
- assembly = null ;
117
- }
86
+ assembly = null ;
118
87
}
119
-
120
- return assembly ;
121
88
}
89
+
90
+ return assembly ;
122
91
}
123
92
}
124
93
}
0 commit comments