c# – 如何在dotnet核心中动态加载程序集

前端之家收集整理的这篇文章主要介绍了c# – 如何在dotnet核心中动态加载程序集前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在构建一个Web应用程序,我想要单独关注,即在不同的项目中进行抽象和实现.

为了实现这一点,我尝试实现了一个组合根概念,其中所有实现都必须有一个ICompositionRootComposer实例来注册服务,类型等.

public interface ICompositionRootComposer
{
    void Compose(ICompositionConfigurator configurator);
}

在构建层次结构中直接引用的项目中,将调用ICompositionRootComposer的实现,并在基础IoC容器中正确注册服务.

当我尝试在项目中注册服务时出现问题,我在其中设置了一个后期构建任务,将构建的dll复制到Web项目的调试文件夹:

cp -R $(TargetDir)"assembly and symbol name"* $(SolutionDir)src/"webproject path"/bin/Debug/netcoreapp1.1

我正在加载装配:(灵感:How to load assemblies located in a folder in .net core console app)

internal class AssemblyLoader : AssemblyLoadContext
{
    private string folderPath;

    internal AssemblyLoader(string folderPath)
    {
        this.folderPath = Path.GetDirectoryName(folderPath);
    }

    internal Assembly Load(string filePath)
    {
        FileInfo fileInfo = new FileInfo(filePath);
        AssemblyName assemblyName = new AssemblyName(fileInfo.Name.Replace(fileInfo.Extension,string.Empty));

        return this.Load(assemblyName);
    }

    protected override Assembly Load(AssemblyName assemblyName)
    {
        var dependencyContext = DependencyContext.Default;
        var ressource = dependencyContext.CompileLibraries.FirstOrDefault(r => r.Name.Contains(assemblyName.Name));

        if(ressource != null)
        {
            return Assembly.Load(new AssemblyName(ressource.Name));
        }

        var fileInfo = this.LoadFileInfo(assemblyName.Name);
        if(File.Exists(fileInfo.FullName))
        {
            Assembly assembly = null;
            if(this.TryGetAssemblyFromAssemblyName(assemblyName,out assembly))
            {
                return assembly;
            }
            return this.LoadFromAssemblyPath(fileInfo.FullName);
        }

        return Assembly.Load(assemblyName);
    }

    private FileInfo LoadFileInfo(string assemblyName)
    {
        string fullPath = Path.Combine(this.folderPath,$"{assemblyName}.dll");

        return new FileInfo(fullPath);
    }

    private bool TryGetAssemblyFromAssemblyName(AssemblyName assemblyName,out Assembly assembly)
    {
        try
        {
            assembly = Default.LoadFromAssemblyName(assemblyName);
            return true;
        }
        catch
        {
            assembly = null;
            return false;
        }
    }
}

有了这个,我就可以加载程序集并调用项目ICompositionRootComposer实现.

但问题是它似乎没有认出我的任何类型.

调用我的配置器

configurator.RegisterTransiantService<IFoo,Foo>();

它应该在IoC中注册IFoo和Foo.
但是在调试时我无法获取类型的信息,即通过Visual Studio Code中调试控制台中的typeof(Foo).

解决方法

Necromancing.

您可以为旧的Assembly.LoadFile创建一个包装类来执行此操作.
这样做的另一个好处是,您可以通过在旧代码库中应用搜索和替换更改来保持向后兼容dotnet-none-core.
您需要通过nuget添加System.Runtime.Loader.

namespace System.Reflection
{

    public class Assembly2
    {


        public static System.Reflection.Assembly LoadFile(string path)
        {
            System.Reflection.Assembly ass = null;

#if NET_CORE
            // Requires nuget - System.Runtime.Loader
            ass = System.Runtime.Loader.AssemblyLoadContext.Default
                   .LoadFromAssemblyPath(path);
#else
            ass = System.Reflection. Assembly.LoadFile(path);
#endif 
            // System.Type myType = ass.GetType("Custom.Thing.SampleClass");
            // object myInstance = Activator.CreateInstance(myType);
            return ass;
        }

    }

}
原文链接:https://www.f2er.com/csharp/96943.html

猜你在找的C#相关文章