Skip to content

Commit 20506fe

Browse files
committed
Bug fix to correctly load reflection based checks for the CodeFactory SDK version on none command libraries.
1 parent a35c1ca commit 20506fe

File tree

1 file changed

+55
-18
lines changed
  • src/CodeFactoryVisualStudio/CodeFactory.VisualStudio.Loader

1 file changed

+55
-18
lines changed

src/CodeFactoryVisualStudio/CodeFactory.VisualStudio.Loader/SdkSupport.cs

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//*****************************************************************************
55

66
using System;
7+
using System.IO;
78
using System.Linq;
89
using 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

Comments
 (0)