无法使用 Entity Framework Core 5.0 从程序集中读取类型
Can't read types from assembly using Entity Framework Core 5.0
我正在尝试从包含 Entity Framework 核心的程序集中读取类型,但出现此错误:
Could not load file or assembly '..file path..\TestRoslyn\Database\bin\Debug\net5.0\Database.dll'. The system cannot find the file specified.
我用来读取类型的代码非常简单:
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}");
}
}
}
}
这按原样工作。但是,当我将一个简单的项目添加到使用一个文件引用 nuget 包 Microsoft.EntityFrameworkCore
(5.0) 的解决方案时:
using Microsoft.EntityFrameworkCore;
namespace Database
{
public class AppContext: DbContext
{
}
}
(为了简单起见,除了基础 class 之外,我没有在 AppContext
class 中包含任何内容。)
当我将带有 EntityFrameworkCore
nuget 包的项目添加到上面的解决方案时 class 我得到上面指出的错误。
不确定是什么原因?我是否需要以某种方式将 nuget 包加载到工作区中?如果是,怎么做?
使用 AssemblyDependencyResolver
和自定义 AssemblyLoadContext
(来自 System.Runtime.Loader)来帮助加载具有依赖项的程序集。
这里是自定义 AssemblyLoadContext
,允许解析依赖项:
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;
}
}
}
可以这样使用:
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}");
}
我正在尝试从包含 Entity Framework 核心的程序集中读取类型,但出现此错误:
Could not load file or assembly '..file path..\TestRoslyn\Database\bin\Debug\net5.0\Database.dll'. The system cannot find the file specified.
我用来读取类型的代码非常简单:
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}");
}
}
}
}
这按原样工作。但是,当我将一个简单的项目添加到使用一个文件引用 nuget 包 Microsoft.EntityFrameworkCore
(5.0) 的解决方案时:
using Microsoft.EntityFrameworkCore;
namespace Database
{
public class AppContext: DbContext
{
}
}
(为了简单起见,除了基础 class 之外,我没有在 AppContext
class 中包含任何内容。)
当我将带有 EntityFrameworkCore
nuget 包的项目添加到上面的解决方案时 class 我得到上面指出的错误。
不确定是什么原因?我是否需要以某种方式将 nuget 包加载到工作区中?如果是,怎么做?
使用 AssemblyDependencyResolver
和自定义 AssemblyLoadContext
(来自 System.Runtime.Loader)来帮助加载具有依赖项的程序集。
这里是自定义 AssemblyLoadContext
,允许解析依赖项:
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;
}
}
}
可以这样使用:
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}");
}