55using System . Collections . Generic ;
66using System . IO ;
77using System . Linq ;
8+ using System . Reflection ;
89using System . Runtime . InteropServices ;
10+ using System . Text . Json ;
11+ using Microsoft . Azure . WebJobs . Script . Description . DotNet ;
912using Microsoft . Azure . WebJobs . Script . ExtensionRequirements ;
1013using Microsoft . Extensions . DependencyModel ;
11- using Newtonsoft . Json . Linq ;
1214
1315namespace Microsoft . Azure . WebJobs . Script . Description
1416{
1517 public static class DependencyHelper
1618 {
1719 private const string AssemblyNamePrefix = "assembly:" ;
18- private static readonly Lazy < Dictionary < string , string [ ] > > _ridGraph = new Lazy < Dictionary < string , string [ ] > > ( BuildRuntimesGraph ) ;
20+ private static readonly Assembly ThisAssembly = typeof ( DependencyHelper ) . Assembly ;
21+ private static readonly string ThisAssemblyName = ThisAssembly . GetName ( ) . Name ;
22+ private static readonly Lazy < Dictionary < string , string [ ] > > RidGraph = new Lazy < Dictionary < string , string [ ] > > ( BuildRuntimesGraph ) ;
23+
1924 private static string _runtimeIdentifier ;
2025
2126 private static Dictionary < string , string [ ] > BuildRuntimesGraph ( )
2227 {
23- var ridGraph = new Dictionary < string , string [ ] > ( ) ;
24- string runtimesJson = GetRuntimesGraphJson ( ) ;
25- var runtimes = ( JObject ) JObject . Parse ( runtimesJson ) [ "runtimes" ] ;
28+ using var stream = GetEmbeddedResourceStream ( "runtimes.json" ) ;
29+
30+ var runtimeGraph = JsonSerializer . Deserialize ( stream , RuntimeGraphJsonContext . Default . RuntimeGraph ) ;
2631
27- foreach ( var runtime in runtimes )
32+ if ( runtimeGraph is not { Runtimes . Count : > 0 } )
2833 {
29- string [ ] imports = ( ( JObject ) runtime . Value ) [ "#import" ]
30- ? . Values < string > ( )
31- . ToArray ( ) ;
34+ throw new InvalidOperationException ( "Failed to deserialize runtimes graph JSON or runtimes section is empty." ) ;
35+ }
36+
37+ var ridGraph = new Dictionary < string , string [ ] > ( runtimeGraph . Runtimes . Count , StringComparer . OrdinalIgnoreCase ) ;
3238
33- ridGraph . Add ( runtime . Key , imports ) ;
39+ foreach ( var ( rid , info ) in runtimeGraph . Runtimes )
40+ {
41+ ridGraph [ rid ] = info . Imports ?? [ ] ;
3442 }
3543
3644 return ridGraph ;
@@ -66,43 +74,43 @@ private static string GetDefaultPlatformRid()
6674 return rid ;
6775 }
6876
69- private static string GetRuntimesGraphJson ( )
77+ private static Stream GetEmbeddedResourceStream ( string fileName )
7078 {
71- return GetResourceFileContents ( "runtimes.json" ) ;
72- }
79+ var stream = ThisAssembly . GetManifestResourceStream ( $ "{ ThisAssemblyName } .{ fileName } ") ;
7380
74- private static string GetResourceFileContents ( string fileName )
75- {
76- var assembly = typeof ( DependencyHelper ) . Assembly ;
77- using ( Stream resource = assembly . GetManifestResourceStream ( $ "{ assembly . GetName ( ) . Name } .{ fileName } ") )
78- using ( var reader = new StreamReader ( resource ) )
79- {
80- return reader . ReadToEnd ( ) ;
81- }
81+ return stream ?? throw new InvalidOperationException ( $ "The embedded resource '{ ThisAssemblyName } .{ fileName } ' could not be found.") ;
8282 }
8383
8484 internal static Dictionary < string , ScriptRuntimeAssembly > GetRuntimeAssemblies ( string assemblyManifestName )
8585 {
86- string assembliesJson = GetResourceFileContents ( assemblyManifestName ) ;
87- JObject assemblies = JObject . Parse ( assembliesJson ) ;
86+ using var stream = GetEmbeddedResourceStream ( assemblyManifestName ) ;
87+ var runtimeAssemblies = JsonSerializer . Deserialize ( stream , RuntimeAssembliesJsonContext . Default . RuntimeAssembliesConfig ) ;
88+
89+ var assemblies = runtimeAssemblies ? . RuntimeAssemblies ?? throw new InvalidOperationException ( $ "Failed to retrieve runtime assemblies from the embedded resource '{ assemblyManifestName } '.") ;
90+
91+ var dictionary = new Dictionary < string , ScriptRuntimeAssembly > ( assemblies . Count , StringComparer . OrdinalIgnoreCase ) ;
92+
93+ foreach ( var assembly in assemblies )
94+ {
95+ dictionary [ assembly . Name ] = assembly ;
96+ }
8897
89- return assemblies [ "runtimeAssemblies" ]
90- . ToObject < ScriptRuntimeAssembly [ ] > ( )
91- . ToDictionary ( a => a . Name , StringComparer . OrdinalIgnoreCase ) ;
98+ return dictionary ;
9299 }
93100
94101 internal static ExtensionRequirementsInfo GetExtensionRequirements ( )
95102 {
96- string requirementsJson = GetResourceFileContents ( "extensionrequirements.json" ) ;
97- JObject requirements = JObject . Parse ( requirementsJson ) ;
103+ const string fileName = "extensionrequirements.json" ;
98104
99- var bundleRequirements = requirements [ "bundles" ]
100- . ToObject < BundleRequirement [ ] > ( ) ;
105+ using var stream = GetEmbeddedResourceStream ( fileName ) ;
106+ var extensionRequirementsInfo = JsonSerializer . Deserialize ( stream , ExtensionRequirementsJsonContext . Default . ExtensionRequirementsInfo ) ;
101107
102- var extensionRequirements = requirements [ "types" ]
103- . ToObject < ExtensionStartupTypeRequirement [ ] > ( ) ;
108+ if ( extensionRequirementsInfo is null )
109+ {
110+ throw new InvalidOperationException ( $ "Failed to deserialize extension requirements from embedded resource '{ fileName } '.") ;
111+ }
104112
105- return new ExtensionRequirementsInfo ( bundleRequirements , extensionRequirements ) ;
113+ return extensionRequirementsInfo ;
106114 }
107115
108116 /// <summary>
@@ -115,7 +123,7 @@ internal static ExtensionRequirementsInfo GetExtensionRequirements()
115123 /// <returns>The runtime fallbacks for the provided identifier.</returns>
116124 public static RuntimeFallbacks GetDefaultRuntimeFallbacks ( string rid )
117125 {
118- var ridGraph = _ridGraph . Value ;
126+ var ridGraph = RidGraph . Value ;
119127
120128 var runtimeFallbacks = new RuntimeFallbacks ( rid ) ;
121129 var fallbacks = new List < string > ( ) ;
@@ -184,7 +192,7 @@ public static List<string> GetRuntimeFallbacks(string rid)
184192 /// <returns> bool if string in was in proper assembly representation format. </returns>
185193 public static bool IsAssemblyReferenceFormat ( string assemblyFormatString )
186194 {
187- return assemblyFormatString != null && assemblyFormatString . StartsWith ( AssemblyNamePrefix ) ;
195+ return assemblyFormatString != null && assemblyFormatString . StartsWith ( AssemblyNamePrefix ) ;
188196 }
189197
190198 /// <summary>
0 commit comments