提问人:Sh'dynasty 提问时间:11/16/2023 最后编辑:Sh'dynasty 更新时间:11/16/2023 访问量:51
Assembly.GetTypes() 由于受保护的抽象方法而抛出 ReflectionTypeLoadException
Assembly.GetTypes() throws ReflectionTypeLoadException because of a protected abstract method
问:
我正在尝试动态加载程序集并获取其中的类型,但我遇到了这个异常:
System.Reflection.ReflectionTypeLoadException: '无法加载一个或多个请求的类型。程序集“My.Namespace.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”中类型为“My.Namespace.Api.Attributes.BasicAuthenticationHandler”的方法“HandleAuthenticateAsync”没有实现。
此类型继承自 abstract 类,该类具有 abstract 方法:Microsoft.AspNetCore.Authentication.AuthenticationHandler
protected abstract Task<AuthenticateResult> HandleAuthenticateAsync();
我正在从单独的 dotnet 7 应用程序加载这些程序集 - 有没有办法加载这些程序集,以便我可以通过反射看到非公共类型/字段/方法/等?我还可以访问项目本身,因此如果有必要,我可以使用不同的设置来构建它们。
我的代码:
internal class Program
{
public static void Main(string[] args)
{
string path = @"C:\mypublish folder\bin\Debug\net6.0\win-x64";
AssemblyLoader loader = new AssemblyLoader(path);
Assembly loadedAssembly = loader.LoadFromAssemblyName(new AssemblyName("My.Namespace.Api"));
LoadReferencedAssembly(loader, loadedAssembly);
Type[] types = loadedAssembly.GetTypes();
}
private static Dictionary<string, Assembly> loadedAssembliesDict { get; set; }
= AppDomain.CurrentDomain.GetAssemblies()
.DistinctBy(x => x.FullName)
.ToDictionary(x => x.FullName);
private static Dictionary<string, AssemblyName> loadedAssemblyNamesDict { get; set; }
= AppDomain.CurrentDomain.GetAssemblies()
.Select(x => x.GetName())
.DistinctBy(x => x.FullName)
.ToDictionary(x => x.FullName);
private static void LoadReferencedAssembly(AssemblyLoader loader, Assembly assembly)
{
if (!loadedAssembliesDict.ContainsKey(assembly.FullName))
loadedAssembliesDict.Add(assembly.FullName, assembly);
AssemblyName currentName = assembly.GetName();
if (!loadedAssemblyNamesDict.ContainsKey(currentName.FullName))
loadedAssemblyNamesDict.Add(currentName.FullName, currentName);
foreach (AssemblyName name in assembly.GetReferencedAssemblies())
{
if (!loadedAssemblyNamesDict.ContainsKey(name.FullName))
{
LoadReferencedAssembly(loader, loader.LoadFromAssemblyName(name));
}
}
}
}
public class AssemblyLoader : AssemblyLoadContext
{
private string folderPath;
public AssemblyLoader(string folderPath)
{
this.folderPath = folderPath;
}
protected override Assembly Load(AssemblyName assemblyName)
{
var deps = DependencyContext.Default;
var res = deps.CompileLibraries.Where(d => d.Name.Contains(assemblyName.Name)).ToList();
if (res.Count > 0)
{
return Assembly.Load(new AssemblyName(res.First().Name));
}
else
{
var apiApplicationFileInfo = new FileInfo($"{folderPath}{Path.DirectorySeparatorChar}{assemblyName.Name}.dll");
if (File.Exists(apiApplicationFileInfo.FullName))
{
var asl = new AssemblyLoader(apiApplicationFileInfo.DirectoryName);
return asl.LoadFromAssemblyPath(apiApplicationFileInfo.FullName);
}
}
return Assembly.Load(assemblyName);
}
}
答: 暂无答案
评论
Assembly.GetTypes()
private static readonly
ConcurrentDictionary<K,V>
).DistinctBy(x => x.FullName)
.DistinctBy(x => x.FullName)