所谓类型转移(Type Forwarding)就是将定义在某个程序集中的类型转移到另一个程序集中。我们先通过一个简单的实例让读者朋友们对类型转移有一个感官上的认识。我们利用Visual Studio创建一个针对.NET Framework 3.5的控制台应用,并编写如下一端简单的程序输出两个常用的类型(Function<T>和TimeZoneInfo)所在程序集的名称。现在我们直接运行这个程序,会在控制台上得到如下所示的输出结果,可以看出.NET Framework 3.5(CLR 2.0)环境下的这两个类型定义在程序集System.Core.dll中。

   1: public class Program
   2: {
   3:     static void Main(string[] args)
   4:     {
   5:         Console.WriteLine(typeof(Func<>).Assembly.FullName);
   6:         Console.WriteLine(typeof(TimeZoneInfo).Assembly.FullName);
   7:     }
   8: }

输出结果:

现在我们对该程序的配置文件(App.config)作如下的修改,其目的在于采用CLR 4.0来运行该程序。再次运行该程序集之后,我们会在控制台上得到不一样的输出结果。通过如下所示的输出结果我们可以看出当.NET Framework从3.5升级到4.0的时候,将原本定义在程序集System.Core.dll中的部分类型转移到了程序集mscorelib.dll之中。

   1: <configuration>
   2:   <startup>
   3:     <supportedRuntime version="v4.0"/>
   4:   </startup>
   5: </configuration>

输出结果:

跨程序集之间的类型转移帮助框架或者类库的提供者解决这样的难题:某个类型在框架1.0版本的时候定义在程序集A中,当升级到2.0的时候被转移到了程序集B中,使用旧版本的应用可以在不做任何修改的情况下直接对使用的升级后的框架程序集。类型转移需要使用到一个特殊的特性TypeForwardedToAttribute,我们现在通过一个简单的实例来演示如何利用这个特性来解决框架或者类库升级过程在类型跨程序集转移的问题。

这个演示的场景如上图所示:代表应用的App.exe在编译的时候引用了代表框架的程序集Lib.dll,具体使用的是定义其中的类型Foobar,框架进行升级之后新增了一个程序集Lib2.dll,原来定义在Lib.dll中的类型Foobar被转移到了Lib2.dll中。充分利用CLR针对类型转移的支持,我们只需要直接部署新版本的Lib.dll(不包含类型Foobar)和Lib2.dll,现有的程序能够照常运行。

我们利用Visual Studio创建了如上图所示的解决方案。类库项目Lib1代表版本1.0的框架,我们将编译生成的程序集名称设置成Lib,并在其中定义了一个类型Foobar。控制台应用直接应用Lib1,并与其中编写了如下一段简单的程序,其目的在于确认类型Foobar所在的程序集。

   1: class Program
   2: {
   3:     static void Main(string[] args)
   4:     {
   5:         Console.WriteLine(typeof(Foobar).AssemblyQualifiedName);
   6:         Console.Read();
   7:     }
   8: }

类库项目Lib2和Lib3编译生成代表框架升级之后的两个程序集,我们通过修改项目属性将目标程序集名称设置成Lib和Lib2,Lib2具有针对Lib3的项目引用。我们在Lib3中重新定义了代表被转移的类型Foobar,而Lib2实际上是一个空的项目。要体现类型Foobar从Lib.dll转移到Lib2.dll,我们需要在Lib2项目上应用如下所示的一个TypeForwardedToAttribute特性(定义在AssemblyInfo.cs中)。

   1: [assembly:TypeForwardedTo(typeof(Foobar))] 

现在我们对整个解决方案进行编译,然后定位到控制台App项目编译后的输出目录(app\bin\debug),并将项目Lib1编译生成的程序集Lib.dll删除,而将Lib2和Lib3编译生成的程序集Lib.dll和Lib2.dll拷贝到该目录下。现在我们直接运行App.exe,我们会在控制台上得到如下所示的输出结果。

如果某个项目应用了TypeForwardedToAttribute特性指向定义在另一个程序集中的被转出类型,类型转移相关的信息会体现在编译生成的元数据中。就我们的实例而言,项目Lib2编译的生成的程序集通过如下的元数据来指向被转移出去的类型所在的目标程序集。

   1: .class extern forwarder Lib.Foobar
   2: {
   3:   .assembly extern Lib2
   4: }

当App.exe被执行的时候,由于元数据体现的依然是针对程序集Lib.dll的引用,所以CLR依然会试图从该程序集中加载类型Foobar。但是通过分析程序集Lib.dll的元数据,CLR知道Foobar已经被转移到程序集Lib2.dll中,所以定义在其中的同名类型Foobar最终会被加载。

转载于:https://www.cnblogs.com/artech/p/type-forwarding.html

框架升级后某个类型所在程序集发生转移,应用还能正常运行吗?相关推荐

  1. onethink 1.0 框架升级ThinkPHP3.2.3后的问题解决

    onethink1.0使用的是ThinkPHP3.2.0,ThinkPHP3.2.3升级后接口有变化.需要修改onethink1.0三个文件才可以运行. 1. Application\Common\C ...

  2. OkHttpUtils-2.0.0 升级后改名 OkGo,全新完美支持 RxJava,比 Retrofit 更简单易用。

    okhttp-OkGo 项目地址:jeasonlzy/okhttp-OkGo 简介:OkHttpUtils-2.0.0 升级后改名 OkGo,全新完美支持 RxJava,比 Retrofit 更简单易 ...

  3. .net框架读书笔记---基础类型

    接上一篇.net框架读书笔记---值类型的装箱与拆箱, 一.Object CLR要求每个类型都最终集成自System.Object类型,这意味着以下两种定义是相同的: //隐式继承自Object cl ...

  4. [Remoting]dotNet Framework升级后Remoting信道使用的安全问题

    [Remoting]dotNet Framework升级后Remoting信道使用的安全问题<?xml:namespace prefix = o ns = "urn:schemas-m ...

  5. 新建mysql 1251,mysql修改密码后无法登陆问题,发生#1251错误

    mysql修改密码后无法登陆问题,发生#1251错误 安装好mysql后修改密码发生:#1251 - Client does not support authentication protocol r ...

  6. 游戏服务器框架升级-无入侵式代理解决方案

    框架升级的目的 主要为了提高服务器的整体承载能力以及游戏的体验. 框架升级遇到的主要障碍 主要遇到的困难,早期最原始的方案,就是直接进行业务代码切割,但对于一个线上 运营了多年的项目,系统模块耦合得非 ...

  7. rowid会变化么_升级后的饿了么,将成为阿里引领数字化的先锋

    7月10日饿了么方面宣布全面升级,将从餐饮外卖平台升级为解决用户身边一切即时需求的生活服务平台.据饿了么CEO王磊(花名昆阳)介绍,新版本的App将于7月17日上线,此次升级将涵盖从送餐升级到提供同城 ...

  8. 数据库升级后,准备使用原有数据文件启动数据库

    因听到以前同事说到11.2.1版本在进行子查询时,速度有时会莫名的慢下来.正好有时间,也是测试服务器, 那就把数据库升级到11.2.3吧.原计划是升级后可以直接使用数据库的相关文件就能启动数据库. 但 ...

  9. 升级后供电不足故障解决攻略

    配件市场推陈出新的速度之快仅人惊叹,半年前配的电脑,突然有一天发现很多游戏不能流畅运行,很多软件打开非常吃力,重新装台电脑根本不现实,这时候最好的办法便是硬件升级.一般情况下,升级硬件时要有一个准确的 ...

最新文章

  1. 有哪些可以免登录的视频会议软件/服务?
  2. 数学好的男生适合学计算机吗,数学好的男生适合读什么专业 2021前景好吗
  3. Android--静默安装
  4. 非Java专家的APM:什么泄漏?
  5. HashMap和ConcurrentHashMap的区别,HashMap的底层源码。
  6. 华为Mate 30系列或下血本采用双主摄方案:CMOS尺寸破纪录
  7. iOS 应用程序的生命周期浅析
  8. 如何更好地理解孩子?
  9. Let’s to be a bug-free programmer
  10. 【去除教育】去除打印教育戳记插件
  11. SQL 分页查询显示
  12. Ubuntu下的几种常见输入法
  13. Python下载所有XKCD漫画
  14. Windows下PuTTY远程连接Linux服务器并上传文件/更改默认端口号
  15. 省市名_code_拼音
  16. 建立简单的VR项目,并且将所需要的资产迁移到新建的VR项目中。
  17. 2018总结-店铺投资篇
  18. 如何用循环执行玩转自定义企业微信机器人?
  19. 二叉树中已知前序和中序求其后序(图解加技巧让你轻松掌握)
  20. 如何才能做一个淡定从容的人呢?

热门文章

  1. 多种方法求解八数码问题
  2. DEL: Open explorer from Console
  3. MySQL 我们来聊聊 count(*) 语句的优化方式有哪些?
  4. 读《人月神话》有感2
  5. SpringMVC表单验证与Velocity整合
  6. [PHP] - 逗号和点号的区别
  7. 2-Eighteenth Scrum Meeting-20151218
  8. mysql 打开远程服务
  9. Android获取MAC地址
  10. git 上传修改文件