5
5
using System . Collections . Generic ;
6
6
using System . IO ;
7
7
using System . Linq ;
8
+ using System . Reflection ;
8
9
using System . Runtime . InteropServices ;
10
+ using System . Text . Json ;
11
+ using Microsoft . Azure . WebJobs . Script . Description . DotNet ;
9
12
using Microsoft . Azure . WebJobs . Script . ExtensionRequirements ;
10
13
using Microsoft . Extensions . DependencyModel ;
11
- using Newtonsoft . Json . Linq ;
12
14
13
15
namespace Microsoft . Azure . WebJobs . Script . Description
14
16
{
15
17
public static class DependencyHelper
16
18
{
17
19
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
+
19
24
private static string _runtimeIdentifier ;
20
25
21
26
private static Dictionary < string , string [ ] > BuildRuntimesGraph ( )
22
27
{
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 ) ;
26
31
27
- foreach ( var runtime in runtimes )
32
+ if ( runtimeGraph is not { Runtimes . Count : > 0 } )
28
33
{
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 ) ;
32
38
33
- ridGraph . Add ( runtime . Key , imports ) ;
39
+ foreach ( var ( rid , info ) in runtimeGraph . Runtimes )
40
+ {
41
+ ridGraph [ rid ] = info . Imports ?? [ ] ;
34
42
}
35
43
36
44
return ridGraph ;
@@ -66,43 +74,43 @@ private static string GetDefaultPlatformRid()
66
74
return rid ;
67
75
}
68
76
69
- private static string GetRuntimesGraphJson ( )
77
+ private static Stream GetEmbeddedResourceStream ( string fileName )
70
78
{
71
- return GetResourceFileContents ( "runtimes.json" ) ;
72
- }
79
+ var stream = ThisAssembly . GetManifestResourceStream ( $ "{ ThisAssemblyName } .{ fileName } ") ;
73
80
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.") ;
82
82
}
83
83
84
84
internal static Dictionary < string , ScriptRuntimeAssembly > GetRuntimeAssemblies ( string assemblyManifestName )
85
85
{
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
+ }
88
97
89
- return assemblies [ "runtimeAssemblies" ]
90
- . ToObject < ScriptRuntimeAssembly [ ] > ( )
91
- . ToDictionary ( a => a . Name , StringComparer . OrdinalIgnoreCase ) ;
98
+ return dictionary ;
92
99
}
93
100
94
101
internal static ExtensionRequirementsInfo GetExtensionRequirements ( )
95
102
{
96
- string requirementsJson = GetResourceFileContents ( "extensionrequirements.json" ) ;
97
- JObject requirements = JObject . Parse ( requirementsJson ) ;
103
+ const string fileName = "extensionrequirements.json" ;
98
104
99
- var bundleRequirements = requirements [ "bundles" ]
100
- . ToObject < BundleRequirement [ ] > ( ) ;
105
+ using var stream = GetEmbeddedResourceStream ( fileName ) ;
106
+ var extensionRequirementsInfo = JsonSerializer . Deserialize ( stream , ExtensionRequirementsJsonContext . Default . ExtensionRequirementsInfo ) ;
101
107
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
+ }
104
112
105
- return new ExtensionRequirementsInfo ( bundleRequirements , extensionRequirements ) ;
113
+ return extensionRequirementsInfo ;
106
114
}
107
115
108
116
/// <summary>
@@ -115,7 +123,7 @@ internal static ExtensionRequirementsInfo GetExtensionRequirements()
115
123
/// <returns>The runtime fallbacks for the provided identifier.</returns>
116
124
public static RuntimeFallbacks GetDefaultRuntimeFallbacks ( string rid )
117
125
{
118
- var ridGraph = _ridGraph . Value ;
126
+ var ridGraph = RidGraph . Value ;
119
127
120
128
var runtimeFallbacks = new RuntimeFallbacks ( rid ) ;
121
129
var fallbacks = new List < string > ( ) ;
@@ -184,7 +192,7 @@ public static List<string> GetRuntimeFallbacks(string rid)
184
192
/// <returns> bool if string in was in proper assembly representation format. </returns>
185
193
public static bool IsAssemblyReferenceFormat ( string assemblyFormatString )
186
194
{
187
- return assemblyFormatString != null && assemblyFormatString . StartsWith ( AssemblyNamePrefix ) ;
195
+ return assemblyFormatString != null && assemblyFormatString . StartsWith ( AssemblyNamePrefix ) ;
188
196
}
189
197
190
198
/// <summary>
0 commit comments