'Can't read types from assembly using Entity Framework Core 5.0
I am trying to read the types out of an assembly that contains Entity Framework Core, but I am getting this error:
Could not load file or assembly '..file path..\TestRoslyn\Database\bin\Debug\net5.0\Database.dll'. The system cannot find the file specified.
The code I am using to read the types is pretty simple:
using System;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis.MSBuild;
namespace TestRoslyn
{
class Program
{
static async Task Main(string[] args)
{
if (!MSBuildLocator.IsRegistered)
MSBuildLocator.RegisterDefaults();
using var w = MSBuildWorkspace.Create();
// Substitute your file location
var basePath = @"C:\Users\username\source\repos\";
var slnFile = @$"{basePath}TestRoslyn\TestRoslyn.sln";
var sln = await w.OpenSolutionAsync(slnFile);
foreach (var p in sln.Projects)
{
var asm = Assembly.LoadFrom(p.OutputFilePath);
foreach(var t in asm.GetTypes())
Console.WriteLine($"{p.OutputFilePath}\t{t.FullName}");
}
}
}
}
This works as is. However, when I add a simple project to the solution that references nuget package Microsoft.EntityFrameworkCore (5.0) with one file:
using Microsoft.EntityFrameworkCore;
namespace Database
{
public class AppContext: DbContext
{
}
}
(To keep it simple, I didn't include anything in the AppContext class except the base class.)
When I add a project with the EntityFrameworkCore nuget package to the solution above with just this class I get the error indicated above.
Not sure what the cause is? Do I need to somehow load the nuget package into the workspace? If so, how?
Solution 1:[1]
Use AssemblyDependencyResolver and custom AssemblyLoadContext (from System.Runtime.Loader) to help load assemblies with dependencies.
Here is the custom AssemblyLoadContext, allowing to resolve dependencies:
using System;
using System.Reflection;
using System.Runtime.Loader;
namespace TestRoslyn
{
public class LoadContext : AssemblyLoadContext
{
private AssemblyDependencyResolver _resolver;
public LoadContext(string assemblyPath)
{
_resolver = new AssemblyDependencyResolver(assemblyPath);
}
protected override Assembly Load(AssemblyName assemblyName)
{
string assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
if (assemblyPath != null)
{
return LoadFromAssemblyPath(assemblyPath);
}
return null;
}
protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
{
string libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
if (libraryPath != null)
{
return LoadUnmanagedDllFromPath(libraryPath);
}
return IntPtr.Zero;
}
}
}
It can be used like this:
foreach (var p in sln.Projects)
{
string outputPath = p.OutputFilePath;
AssemblyName assemblyName = AssemblyName.GetAssemblyName(outputPath);
LoadContext loadContext = new LoadContext(outputPath);
Assembly asm = loadContext.LoadFromAssemblyName(assemblyName);
foreach (var t in asm.GetTypes())
Console.WriteLine($"{p.OutputFilePath}\t{t.FullName}");
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ruslan Gilmutdinov |
