• 为.Net项目添加动态库加载路径


    本文分别基于.Net Framework和.Net Core的WPF应用程序为例,来说明如何为.Net项目添加自定义动态库加载路径。本文基于.Net Core创建WPF时,使用了.Net5作为目标框架。

    1、.Net Framework

    在基于.Net Framework的WPF项目中,直接在配置文件(App.config)中添加runtime节点即可。

    <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <!-- 指定加载程序集时公共语言运行时搜索的子目录, 
             其中privatePath是相对于*.exe.config文件的相对路径,
             多个文件夹以分号分隔。-->
        <probing privatePath="LibsLib1;LibsLib2"/>
      </assemblyBinding>
    </runtime>

    2、.Net5

    在基于.Net5的WPF项目中,使用privatePath已经不能够实现指定文件夹程序集的加载了,这大概时因为在.Net5中,程序集的加载依赖于应用程序的.deps.json文件,而privatePath指定的文件夹中的程序集不会被添加到.deps.json文件中。

    基于"<probing privatePath="..." /> doesn't work in .Net 5.0",在项目文件(配置文件中应该也可以)设置动态库加载路径,然后基于AssemblyLoadContext类的Resolving事件,在应用程序查找未知类型时加载配置文件中的动态库。

    (1)在.csproj文件中设置动态库路径

    <ItemGroup>
      <RuntimeHostConfigurationOption Include="SubdirectoriesToProbe" Value="Plugins" />
    </ItemGroup>

    (2)在代码中实现类型动态加载

    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            //加载程序集事件
            AssemblyLoadContext.Default.Resolving += ResolveAssembly;
    
            base.OnStartup(e);
        }
        
        //加载指定位置程序集
        private static Assembly ResolveAssembly(AssemblyLoadContext assemblyLoadContext, AssemblyName assemblyName)
        {
            var probeSetting = AppContext.GetData("SubdirectoriesToProbe") as string;
            if (string.IsNullOrEmpty(probeSetting))
            {
                return null;
            }
    
            foreach (var subDirectory in probeSetting.Split(';'))
            {
                var pathMaybe = Path.Combine(AppContext.BaseDirectory, subDirectory, $"{assemblyName.Name}.dll");
                if (File.Exists(pathMaybe))
                {
                    return assemblyLoadContext.LoadFromAssemblyPath(pathMaybe);
                }
            }
    
            return null;
        }
    }
  • 相关阅读:
    Linux下退出vi编辑模式
    Manifest merger failed : uses-sdk:minSdkVersion 16 cannot be smaller than version 17 declared in library(开发日志28)
    Could not download bmob-sdk.arr(cn.bmob.android:bmob-sdk:3.7.8)(开发日志25)
    本周总结
    思考概念方式
    面试体系目录
    2020面试记录
    日志
    redis 实现分布式锁
    SpringMvc servlet 拦截器 过滤器关系和区别及执行顺序
  • 原文地址:https://www.cnblogs.com/xhubobo/p/15093866.html
Copyright © 2020-2023  润新知