延迟加载是一个很大的诱惑,可以达到一些比较好的效果,比如:

1、在实体框架中,由于关联数据的数量和使用时机是不确定的,通过延迟加载,仅在使用的时候去执行关联数据的查询操作,减少无谓的数据查询操作,可以降低单次数据查询执行的时间,提升系统的性能。

2、在一个插件平台中启动平台时只加载必需的程序集,当执行到具体插件时再加载插件相关的程序集,仅在需要的时候加载资源,可以减少插件平台的启动时间,使内存的占用更合理些。

延迟加载可以使资源的占用更加合理,并提升一定的性能,当然也有一些例子来说明延迟加载的坏处,这就需要根据实际的情况去考量,不是这篇文章的目的。

言归正传,在ASP.NET Web Forms开发模式中,程序集一般都放到bin目录下,或者在web.config中通过配置codebase或者probing节点指定程序集目录,应用程序启动时会从这些位置自动加载程序集。我们要使用延迟加载,就不能将程序集放到这些地方,将需要延迟加载的程序集放到一些有规则可循的目录是一种比较好的方式。比如:

root

|–bin

|–lazyload

|    |–bin1

|    |–bin2

将这些程序集都放到一个lazyload的目录中,然后在其中根据程序集的划分建立不同的子目录,根据需要去不同的目录中加载程序集。

那么使用什么方法加载程序集呢?

Assembly类提供了几个静态方法:Load、LoadFile、LoadFrom,可以通过这几个方法将dll文件加载到当前应用程序域的程序集中。

关于这几个方法如何选择,网上有一些总结,这里不做讨论。以下是一些总结:

http://www.cnblogs.com/xuqingfeng/archive/2012/05/22/assembly-load-loadfrom-loadfile-details.html

http://msdn.microsoft.com/zh-cn/library/dd153782(v=vs.110).aspx

实现程序集的延迟加载需要扩展两个地方:

1、依赖程序集的延迟加载

通过订阅当前应用程序域的AssemblyResolve事件,应用程序域在加载依赖程序集时如果找不到就会触发这个事件。

在这个事件中我们可以通过一些规则找到需要加载的程序集文件,然后通过Assembly的加载方法加载到内存,并返回。

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
 
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
Assembly assembly = null;
 
//加载程序集部分省略
 
return assembly;
}

2、页面动态编译所需程序集的延迟加载

aspx页面在首次访问时会进行编译,编译时需要页面绑定的类所在的程序集。默认情况下这些程序集是在程序启动的时候自动加载的,从.net4开始,微软提供了一个应用程序启动的扩展支持System.Web.PreApplicationStartMethod,也可以在这里通过程序加载程序集,但还是达不到延迟加载的效果。

aspx页面的编译是通过BuildManager实现的,调用BuildManager.AddReferencedAssembly方法可以添加程序集,但是这个方法只能在上边提到的扩展支持中调用,程序启动后再调用就会抛出异常(可能是.net4.0还有些东西没协调好),此路不通。既然不能通过方法添加,那是不是可以直接加入到BuildManager的程序集集合中,很不幸全是私有的,有兴趣的可以自己反编译看看。

私有的其实也不是没有办法可以获取,使用反射,还好BuildManager有一个静态的属性TheBuildManager,通过反射获取这个属性的值就可以得到内部的BuildManager实例,修改程序集的集合就不成问题了。

// 获取BuildManager的实例
PropertyInfo buildmanagerProperty = Type.GetTypeFromHandle(typeof(BuildManager).TypeHandle).GetProperty("TheBuildManager", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty);
BuildManager buildmanager = buildmanagerProperty.GetValue(nullnullas BuildManager;
 
// 获取TopLevelReferencedAssemblies
PropertyInfo topLevelReferencedAssembliesProperty = Type.GetTypeFromHandle(typeof(BuildManager).TypeHandle).GetProperty("TopLevelReferencedAssemblies", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty);
IList assemblies = topLevelReferencedAssembliesProperty.GetValue(buildmanager, nullasIList;
 
// 添加程序集
Assembly assembly = null;
 
//加载程序集部分省略
 
assemblies.Add(assembly);

这段程序要在页面编译之前调用,比如PageHandlerFactory的GetHandler方法中。

通过这两个扩展基本上就可以实现程序集的延迟加载了,能用来干什么就要看自己了。博客园有个人搞了个OSGI.NET,就用到文中的两个方法。

当然上边只是初步给出了解决问题的方法,如果要实际使用,可能要考虑更多的问题,比如多线程同步问题、程序集多版本问题等等,有兴趣的可以写写看。

本人独立博客地址:http://blog.bossma.cn/dotnet/asp-net-how-to-lazy-load-assembly/

转载请注明出处。

ASP.NET Web Froms开发模式中实现程序集的延迟加载的更多相关文章

  1. Asp.Net Web API开发微信后台

    如果说用Asp.Net开发微信后台是非主流,那么Asp.Net Web API的微信后台绝对是不走寻常路. 需要说明的是,本人认为Asp.Net Web API在开发很多不同的请求方法的Restful ...

  2. 微软实战训练营(X)重点班第(1)课:SOA必备知识之ASP.NET Web Service开发实战

    微软实战训练营 上海交大(A)实验班.(X)重点班 内部课程资料 链接:http://pan.baidu.com/s/1jGsTjq2 password:0wmf <微软实战训练营(X)重点班第 ...

  3. asp.net简述Web Forms开发模式

    详情请查阅:http://www.runoob.com/aspnet/aspnet-intro.html 1.Web Forms 是三种创建 ASP.NET 网站和 Web 应用程序的编程模式中的一种 ...

  4. ASP.NET MVC——CodeFirst开发模式

    Entity Framework框架提供了几种开发模式,比如Database First,Model First,Code First.Database First是最老也是应用得最广泛的一种设计方式 ...

  5. asp.net简述WP开发模式

    详情请参考菜鸟教程:http://www.runoob.com/aspnet/aspnet-tutorial.html 1.ASP.NET 是一个使用 HTML.CSS.JavaScript 和服务器 ...

  6. Java web MVC开发模式入门感悟

    当我进行第一个完整的java web项目的开发时,对以前所学的Java web知识体系有了一个清晰的进阶认识.我觉得非常有必要对此进行必要的总结. MVC,意指model(数据持久层)+viewer( ...

  7. ASP.NET Web Form和MVC中防止F5刷新引起的重复提交问题

    转载 http://www.cnblogs.com/hiteddy/archive/2012/03/29/Prevent_Resubmit_When_Refresh_Reload_In_ASP_NET ...

  8. ASP.NET Web API Basic Identity 中的基本身份验证

    缺点 用户凭证在请求中发送. 凭据作为明文发送. 每个请求都会发送凭据. 无法注销,除非结束浏览器会话. 易于跨站点请求伪造(CSRF); 需要反CSRF措施. 优点 互联网标准. 受所有主要浏览器支 ...

  9. asp.net简述MVC开发模式

    详情请参考:http://www.runoob.com/aspnet/mvc-intro.html 1.MVC 是三种 ASP.NET 编程模式中的一种.MVC 是一种使用 MVC(Model Vie ...

随机推荐

  1. hdoj 1878 欧拉回路

    欧拉回路 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  2. [iOS基础控件 - 1] UI概念

    A. UIView 1.概念      属于UIKit框架      屏幕上能看得见摸得着的东西就是UIView,比如屏幕上的按钮.文字.图片      翻译为:视图/控件/组件      UIBut ...

  3. iOS中几种定时器 - 控制了时间,就控制了一切

    在软件开发过程中,我们常常需要在某个时间后执行某个方法,或者是按照某个周期一直执行某个方法.在这个时候,我们就需要用到定时器. 然而,在iOS中有很多方法完成以上的任务,到底有多少种方法呢?经过查阅资 ...

  4. HDU 3635 并查集+路径压缩+记录每个点移动次数

    题意: 给定n个点 oper个操作 每个点有1个龙珠 下面2种操作: T u v 把u点所有龙珠搬到v Q u  问u点当前所在城市 u点所在城市有几个龙珠 u点被移动几次 思路: 并查集可以求出 u ...

  5. 剑指OFFER之丑数(九度OJ1214)

    题目描述: 把只包含因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含因子7.习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 输入: 输 ...

  6. 多线程操作Coredata(转)

    第一步:搭建 Core Data 多线程环境这个问题首先要解决的是搭建 Core Data 多线程环境.Core Data 对并发模式的支持非常完备,NSManagedObjectContext 的指 ...

  7. zabbix 3.0 安装

    zabbix3.0安装注意: 1.PHP要5.4版本以上 2.防火墙关闭 3.selinux关闭 注:本操作系统为centos 6.5 X86   操作步骤 一.安装PHP 添加 epel 源 # r ...

  8. btrace拓展工具-java应用性能诊断优化利器

    Btrace是一个实时监控工具,可以无需修改应用代码(事实上它修改了字节码),来达到不可告人的秘密!这是性能调优和诊断的利器! 它可以获取应用程序代码的执行时间,他可以让你无需修改代码,帮你做时间的打 ...

  9. 黑马程序猿_7K面试题之交通灯系统

    交通灯信号模拟系统 一.概述 模拟实现十字路口的交通灯管理系统逻辑,详细需求例如以下:(需求直接来源于老师的文档) ①      异步随机生成依照各个路线行驶的车辆. 比如: 由南向而来去往北向的车辆 ...

  10. HDU 1718 Rank counting sort解法

    本题是利用counting sort的思想去解题. 注意本题,好像利用直接排序,然后查找rank是会直接被判WA的.奇怪的推断系统. 由于分数值的范围是0到100,很小,而student 号码又很大, ...