前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从AppDomain迁移到AssemblyLoadContext

从AppDomain迁移到AssemblyLoadContext

作者头像
李明成
发布2020-02-12 11:31:09
1.4K0
发布2020-02-12 11:31:09
举报
文章被收录于专栏:dotNET知音dotNET知音

AssemblyLoadContext

基本上AssemblyLoadContext是AppDomain的继承者,它提供相同而且更多的功能-除了安全边界(隔离)。最小的安全边界是进程,因此你将需要使用进程间通信来正确隔离数据和代码执行。

官网文档中提到Appdomain已经过时了,为了兼容旧的版本,提供了部分功能。建议在.NET Core3.0及更高的版本使用AssemblyLoadContext。

从AppDomain迁移到AssemblyLoadContext

也许你仍在应用程序中使用AppDomain。现在,以下代码显示如何用AssemblyLoadContext的相应方法去替换掉AppDomain方法:

  • 获取所有程序集
代码语言:javascript
复制
var assembliesInAppDomain = AppDomain.CurrentDomain.GetAssemblies();
var assembliesInAssemblyLoadContext = AssemblyLoadContext.Default.Assemblies;
  • 加载一个程序集
代码语言:javascript
复制
AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName("path"));
AssemblyLoadContext.Default.LoadFromAssemblyName(AssemblyName.GetAssemblyName("path"));
  • 加载一个程序集 路径或者字节数组:
代码语言:javascript
复制
AppDomain.CurrentDomain.Load(File.ReadAllBytes("path"));
AssemblyLoadContext.Default.LoadFromStream(File.OpenRead("path"));
// or
AssemblyLoadContext.Default.LoadFromAssemblyPath("path");
  • 测试封装的获取程序集方法GetAssemblies

准备工作:

  1. 创建一个控制台程序
  2. 添加一个类库项目,命名为AA.Service

在控制台应用程序,添加一个类TypeFinder代码如下:

代码语言:javascript
复制
 public class TypeFinder
    {
        /// <summary>
        /// 获取物理路径 
        /// </summary>
        /// <returns>\bin\Debug\netcoreapp3.0</returns>
        public virtual string GetBinDirectory()
        {
            return AppContext.BaseDirectory;
        }
        /// <summary>
        /// 获取程序集
        /// </summary>
        /// <returns></returns>
        public IList<Assembly> GetAssemblies()
        {
            var binPath = GetBinDirectory();
            var addedAssemblyNames = new List<string>();
            var assemblies = new List<Assembly>();

            //
            foreach (var assembly in AssemblyLoadContext.Default.Assemblies.Where(a=>IsNotSysAssembly(a.FullName)))
            {
                if (addedAssemblyNames.Contains(assembly.FullName))
                    continue;
                addedAssemblyNames.Add(assembly.FullName);
            }

            foreach (var dllPath in Directory.GetFiles(binPath, "*.dll",
                 SearchOption.TopDirectoryOnly))
            {
                try
                {
                    var an = AssemblyName.GetAssemblyName(dllPath);
                    if (!addedAssemblyNames.Contains(an.FullName))
                    {
                        AssemblyLoadContext.Default.LoadFromAssemblyName(an);
                    }
                }
                catch (BadImageFormatException ex)
                {
                    Trace.TraceError(ex.ToString());
                }
            }

            foreach (var assembly in AssemblyLoadContext.Default.Assemblies.Where(a => IsNotSysAssembly(a.FullName)))
            {
                if (addedAssemblyNames.Contains(assembly.FullName))
                    continue;

                assemblies.Add(assembly);
            }
            return assemblies;
        }

        /// <summary>
        /// 排除系统程序集
        /// </summary>
        /// <param name="assemblyName"></param>
        /// <returns></returns>
        private bool IsNotSysAssembly(string assemblyName) 
        {
            return !assemblyName.StartsWith("Microsoft.")
                      && !assemblyName.StartsWith("System.")
                      && !assemblyName.StartsWith("Newtonsoft.")
                      && assemblyName != "netstandard";
        }
    }

在控制台应用程序添加引用AA.Service类库,生成查看bin文件,出现了AA.Service.dll

调用代码输出(排除系统dll以Microsoft、system开头的)程序集:

代码语言:javascript
复制
var assemblies= new TypeFinder().GetAssemblies();
            foreach (var a in assemblies) 
            {
                Console.WriteLine(a.FullName);
            }

输出

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 dotNET知音 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档