简体   繁体   中英

how to resolve assembly dependency in dotnet core?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM