Asp.Net Core: Reflecting an Asp.Net Assembly throw exception
I'm currently implementing an elementary solution to load the Services in an Asp.Net Core by reflection instead of having to pass every single type. To have some wiggle-room, I created a static helper returning me the assembly-types using the new core-reflection types:
internal static class ReflectionTypeHelper
{
private static readonly Assembly _currentAssembly = typeof(ServiceContainerInitializer).GetTypeInfo().Assembly;
internal static IReadOnlyCollection<Type> ScanAssembliesForTypes(Func<Type, bool> predicate)
{
var result = new List<Type>();
var appAssemblies = GetApplicationAssemblies();
foreach (var ass in appAssemblies)
{
var typesFromAssembly = ass.GetTypes().Where(predicate);
result.AddRange(typesFromAssembly);
}
return result;
}
private static IEnumerable<Assembly> GetApplicationAssemblies()
{
var consideredFileExtensions = new[]
{
".dll",
".exe"
};
var result = new List<Assembly>();
var namespaceStartingPart = GetNamespaceStartingPart();
var assemblyPath = GetPath();
IEnumerable<string> assemblyFiles = Directory.GetFiles(assemblyPath);
var fileInfos = assemblyFiles.Select(f => new FileInfo(f));
fileInfos = fileInfos.Where(f => f.Name.StartsWith(namespaceStartingPart) && consideredFileExtensions.Contains(f.Extension.ToLower()));
// Net.Core can't load the Services for some reason, so we exclude it at the moment
//fileInfos = fileInfos.Where(f => f.Name.IndexOf("Services", StringComparison.OrdinalIgnoreCase) == -1);
foreach (var fi in fileInfos)
{
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(fi.FullName);
result.Add(assembly);
}
return result;
}
private static string GetNamespaceStartingPart()
{
var fullNamespace = _currentAssembly.FullName;
var splittedNamespace = fullNamespace.Split('.');
var result = string.Concat(splittedNamespace[0], ".", splittedNamespace[1]);
return result;
}
private static string GetPath()
{
var codeBase = _currentAssembly.CodeBase;
var uri = new UriBuilder(codeBase);
var result = Uri.UnescapeDataString(uri.Path);
result = Path.GetDirectoryName(result);
return result;
}
}
As you can probably see in the code-comment, I can't load the "Services"-Assembly, which I creted from the "ASP.NET Core Web Application (.Net Core)" - Project template.
Unfortunately, the exception is quite generic
Could not load file or assembly 'Argusnet.Pis.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Also, the file is there as expected. I did find some hints on GitHub-Issues regarding this topic, but they're all solved in the Release Candidates.
Interesting enough, all other assemblies work as you'd expect, so there has to be something specific regarding this assembly-types?
Edit: Screenshot of the exception:
One of the reason why it's failing to load might be the mismatch in target processor architecture selected during compiling. Argusnet.Pis.Services
might be compiled with x86 configuration and the client application trying to load might be built using the x64 option during compiling Or the other way around. Make sure both projects have the same option(x86 or x64) set before building them. Otherwise try building them with Any CPU
option.