I have multiple project as bellow:
1- Infrastructure: this is classLibrary project and contains infrastructural classes, interfaces and etc.
2- Runable Project: this is asp.net core 5 project and used for launch other business project and has reference from Infrastructure
project
3- Business solution : this has multiple class library project for api, service, domain, ...
layers
in Infrastructure
project there is an interface as bellow:
using Microsoft.Extensions.DependencyInjection;
namespace Infrastructure
{
public interface IModuleLoader
{
void Register(IServiceCollection serviceCollection);
}
}
in the Business.Api
project there is class that implement IModuleLoader
interface
namespace Business.Api
{
public class BusinessModuleLoader : IModuleLoader
{
public void Register(IServiceCollection services)
{
services.AddControllers().AddApplicationPart(this.GetType().Assembly);
//...
}
}
}
in the Runable
Project have this class for loading business Assembly project
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;
}
}
}
}
the Business.Api
assembly loaded and BusinessModuleLoader
type exists in loaded assembly but
doesn't match in this line of code var moduleLoader = asm.GetTypes().FirstOrDefault(p => mtype.IsAssignableFrom(p));
and varable moduleLoader
is null
How can I solve this problem?
you can try loading all the assemblies first and then looping for register
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);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.