44//*****************************************************************************
55
66using System ;
7+ using System . IO ;
78using System . Linq ;
89using System . Reflection ;
910
@@ -29,6 +30,13 @@ public static class SdkSupport
2930 /// </summary>
3031 public const string NuGetSdkVersion = "1.22320.1" ;
3132
33+ /// <summary>
34+ /// The name of the assembly type for the CodeFactory SDK version attribute.
35+ /// </summary>
36+ public const string CodeFactorySdkVersionAttributeName = "AssemblyCFSdkVersion" ;
37+
38+ public const string CodeFactoryAssemblyName = "CodeFactory" ;
39+
3240 /// <summary>
3341 /// Checks the assembly to see if it was created by a CodeFactory SDK. If so it checks the version to confirms it can be used by the runtime.
3442 /// </summary>
@@ -37,27 +45,21 @@ public static void SupportedAssembly(Assembly sourceAssembly)
3745 {
3846 if ( sourceAssembly == null ) return ;
3947
48+ //Adding a assembly resolver if the child assembly needs to be loaded
49+ AppDomain . CurrentDomain . ReflectionOnlyAssemblyResolve += CurrentDomain_ReflectionOnlyAssemblyResolve ;
50+
51+ Assembly workAssembly = sourceAssembly ;
52+
4053 bool cfAssembly = false ;
4154 try
4255 {
43- cfAssembly = sourceAssembly . GetReferencedAssemblies ( ) . Any ( a=> a . Name == "CodeFactory" ) ;
44-
45- var sdkVersionObject = sourceAssembly . GetCustomAttributes ( typeof ( AssemblyCFSdkVersion ) , false ) ;
56+ cfAssembly = workAssembly . GetReferencedAssemblies ( ) . Any ( a => a . Name == CodeFactoryAssemblyName ) ;
4657
47- if ( sdkVersionObject == null )
48- {
49- if ( cfAssembly ) throw new UnsupportedSdkLibraryException ( sourceAssembly . FullName , "0.0.0.0" , MinVersion ,
50- MaxVersion ) ;
58+ var customAttributes = CustomAttributeData . GetCustomAttributes ( workAssembly ) ;
5159
52- return ;
53- }
60+ var versionSdk = customAttributes . FirstOrDefault ( c => c . AttributeType . Name == CodeFactorySdkVersionAttributeName ) ;
5461
55-
56- var sdkVersion = sdkVersionObject [ 0 ] as AssemblyCFSdkVersion ;
57-
58- if ( sdkVersion == null ) return ;
59-
60- var rawVersion = sdkVersion . Value ;
62+ var rawVersion = versionSdk ? . ConstructorArguments . FirstOrDefault ( ) . Value as string ;
6163
6264 if ( string . IsNullOrEmpty ( rawVersion ) ) return ;
6365
@@ -67,7 +69,7 @@ public static void SupportedAssembly(Assembly sourceAssembly)
6769 int maxVersion = Convert . ToInt32 ( MaxVersion . Replace ( "." , "" ) ) ;
6870
6971 if ( libraryVersion < minVersion || libraryVersion > maxVersion )
70- throw new UnsupportedSdkLibraryException ( sourceAssembly . FullName , rawVersion , MinVersion ,
72+ throw new UnsupportedSdkLibraryException ( workAssembly . FullName , rawVersion , MinVersion ,
7173 MaxVersion ) ;
7274
7375 }
@@ -77,10 +79,45 @@ public static void SupportedAssembly(Assembly sourceAssembly)
7779 }
7880 catch ( Exception )
7981 {
80- if ( cfAssembly ) throw new UnsupportedSdkLibraryException ( sourceAssembly . FullName , "0.0.0.0" , MinVersion ,
81- MaxVersion ) ;
82+ if ( cfAssembly )
83+ throw new UnsupportedSdkLibraryException ( workAssembly . FullName , "0.0.0.0" , MinVersion ,
84+ MaxVersion ) ;
85+ }
86+ finally
87+ {
88+ //Removing our delegate from the assembly resolver.
89+ AppDomain . CurrentDomain . ReflectionOnlyAssemblyResolve -= CurrentDomain_ReflectionOnlyAssemblyResolve ;
90+ }
91+
92+ }
93+
94+ /// <summary>
95+ /// Event handler that resolves assemblies that are not in the reflection only context.
96+ /// </summary>
97+ /// <param name="sender">Application domain that needs to resolve.</param>
98+ /// <param name="args">Resolve arguments that contains the information needed for resolution.</param>
99+ /// <returns>The reflection only assembly or null if it cannot be loaded.</returns>
100+ private static Assembly CurrentDomain_ReflectionOnlyAssemblyResolve ( object sender , ResolveEventArgs args )
101+ {
102+ var assemblies = AppDomain . CurrentDomain . GetAssemblies ( ) ;
103+
104+ var loadedAssembly = assemblies . FirstOrDefault ( a => a . FullName == args . Name ) ;
105+
106+ if ( loadedAssembly != null )
107+ {
108+ return Assembly . ReflectionOnlyLoadFrom ( loadedAssembly . Location ) ;
82109 }
83110
111+ var filenamePosition = args . Name . IndexOf ( ',' ) ;
112+ var fileName = $ "{ args . Name . Substring ( 0 , filenamePosition ) } .dll";
113+
114+ var directoryPath = Path . GetDirectoryName ( args . RequestingAssembly . Location ) ;
115+
116+ if ( string . IsNullOrEmpty ( directoryPath ) ) return null ;
117+
118+ var filePath = Path . Combine ( directoryPath , fileName ) ;
119+
120+ return ! File . Exists ( filePath ) ? null : Assembly . ReflectionOnlyLoadFrom ( filePath ) ;
84121 }
85122 }
86123}
0 commit comments