我有多个项目如下:
1- 基础设施:这是 classLibrary 项目,包含基础设施类、接口等。
2- Runable Project:这是 asp.net core 5 项目,用于启动其他业务项目,并参考 Infrastructure
项目
3- 业务解决方案:这具有用于 api, service, domain, ...
层的多个类库项目
在 Infrastructure
项目中有一个界面如下:
using Microsoft.Extensions.DependencyInjection;
namespace Infrastructure
{
public interface IModuleLoader
{
void Register(IServiceCollection serviceCollection);
}
}
在 Business.Api
项目中有实现 IModuleLoader
接口的类
namespace Business.Api
{
public class BusinessModuleLoader : IModuleLoader
{
public void Register(IServiceCollection services)
{
services.AddControllers().AddApplicationPart(this.GetType().Assembly);
//...
}
}
}
在Runable
项目中有这个类用于加载业务组装项目
public static class ModuleLoaderHelper
{
public static void LoadModules(this IServiceCollection services)
{
AutoLoading(services);
}
private static void AutoLoading(IServiceCollection services)
{
var path = AppDomain.CurrentDomain.BaseDirectory;
DirectoryInfo di = new DirectoryInfo(path);
FileInfo[] fis = di.GetFiles("Business.Api.dll");
var mtype = typeof(Infrastructure.IModuleLoader);
foreach (var f in fis)
{
try
{
var loadContext = new PluginLoadContext(f.FullName);
var asm = loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(f.FullName)));
var moduleLoader = asm.GetTypes().FirstOrDefault(p => mtype.IsAssignableFrom(p));
if (moduleLoader == null)
continue;
Infrastructure.IModuleLoader loader = (Infrastructure.IModuleLoader)Activator.CreateInstance(moduleLoader);
loader.Register(services);
}
catch (Exception exp)
{
Console.WriteLine(exp.Message + exp.StackTrace);
}
}
}
class PluginLoadContext : AssemblyLoadContext
{
private AssemblyDependencyResolver _resolver;
public PluginLoadContext(string pluginPath)
{
_resolver = new AssemblyDependencyResolver(pluginPath);
}
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;
}
}
}
}
已加载的 Business.Api
程序集和 BusinessModuleLoader
类型存在于已加载的程序集中但是
在这行代码中不匹配 var moduleLoader = asm.GetTypes().FirstOrDefault(p => mtype.IsAssignableFrom(p));
并且变量 moduleLoader
是 null
我该如何解决这个问题?
答案 0 :(得分:0)
您可以尝试先加载所有程序集,然后循环注册
private static void AutoLoading(IServiceCollection services)
{
var path = AppDomain.CurrentDomain.BaseDirectory;
DirectoryInfo di = new DirectoryInfo(path);
FileInfo[] fis = di.GetFiles("Business.*.dll");
var mtype = typeof(Infrastructure.IModuleLoader);
foreach (var f in fis)
{
try
{
var res = AppDomain.CurrentDomain.GetAssemblies().Any(loadedAssembly => AssemblyName.ReferenceMatchesDefinition(loadedAssembly.GetName(), AssemblyName.GetAssemblyName(f)));
if (!res)
{
AppDomain.CurrentDomain.Load(Assembly.LoadFrom(f).GetName());
}
}
catch (Exception exp)
{
Console.WriteLine(exp.Message + exp.StackTrace);
}
}
try
{
_modules = AppDomain.CurrentDomain.GetAssemblies().Where(assembly => assembly.FullName!.StartsWith("Business.*.dll"))
.SelectMany(assembly => assembly.GetTypes()).Where(type =>
{
if (type.IsClass && !type.IsAbstract)
{
bool isAssignable = typeof(Infrastructure.IModuleLoader).IsAssignableFrom(type);
return isAssignable;
}
return false;
}).ToList()
.Select(Activator.CreateInstance).Cast<Infrastructure.IModuleLoader>().ToList();
foreach (var module in _modules)
{
module.Register(services);
}
}
catch (Exception exp)
{
Console.WriteLine(exp.Message + exp.StackTrace);
}
}