ASP.NET Web Froms开发模式中实现程序集的延迟加载
延迟加载是一个很大的诱惑,可以达到一些比较好的效果,比如:
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(null, null) as BuildManager; |
// 获取TopLevelReferencedAssemblies |
PropertyInfo topLevelReferencedAssembliesProperty = Type.GetTypeFromHandle(typeof(BuildManager).TypeHandle).GetProperty("TopLevelReferencedAssemblies", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty); |
IList assemblies = topLevelReferencedAssembliesProperty.GetValue(buildmanager, null) asIList; |
// 添加程序集 |
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开发模式中实现程序集的延迟加载的更多相关文章
- Asp.Net Web API开发微信后台
如果说用Asp.Net开发微信后台是非主流,那么Asp.Net Web API的微信后台绝对是不走寻常路. 需要说明的是,本人认为Asp.Net Web API在开发很多不同的请求方法的Restful ...
- 微软实战训练营(X)重点班第(1)课:SOA必备知识之ASP.NET Web Service开发实战
微软实战训练营 上海交大(A)实验班.(X)重点班 内部课程资料 链接:http://pan.baidu.com/s/1jGsTjq2 password:0wmf <微软实战训练营(X)重点班第 ...
- asp.net简述Web Forms开发模式
详情请查阅:http://www.runoob.com/aspnet/aspnet-intro.html 1.Web Forms 是三种创建 ASP.NET 网站和 Web 应用程序的编程模式中的一种 ...
- ASP.NET MVC——CodeFirst开发模式
Entity Framework框架提供了几种开发模式,比如Database First,Model First,Code First.Database First是最老也是应用得最广泛的一种设计方式 ...
- asp.net简述WP开发模式
详情请参考菜鸟教程:http://www.runoob.com/aspnet/aspnet-tutorial.html 1.ASP.NET 是一个使用 HTML.CSS.JavaScript 和服务器 ...
- Java web MVC开发模式入门感悟
当我进行第一个完整的java web项目的开发时,对以前所学的Java web知识体系有了一个清晰的进阶认识.我觉得非常有必要对此进行必要的总结. MVC,意指model(数据持久层)+viewer( ...
- ASP.NET Web Form和MVC中防止F5刷新引起的重复提交问题
转载 http://www.cnblogs.com/hiteddy/archive/2012/03/29/Prevent_Resubmit_When_Refresh_Reload_In_ASP_NET ...
- ASP.NET Web API Basic Identity 中的基本身份验证
缺点 用户凭证在请求中发送. 凭据作为明文发送. 每个请求都会发送凭据. 无法注销,除非结束浏览器会话. 易于跨站点请求伪造(CSRF); 需要反CSRF措施. 优点 互联网标准. 受所有主要浏览器支 ...
- asp.net简述MVC开发模式
详情请参考:http://www.runoob.com/aspnet/mvc-intro.html 1.MVC 是三种 ASP.NET 编程模式中的一种.MVC 是一种使用 MVC(Model Vie ...
随机推荐
- 【noip2011】观光公交
题解: 做这题的时候为了敢速度- - 直接orz了神小黑的题解 其实我还是有想一个拙计的方法的- - dp:f[i][j] 表示到i点使用j个加速器 在i前上车的人的时间和 轻松愉悦转移之 - - 但 ...
- Send email alert from Performance Monitor using PowerShell script (检测windows服务器的cpu 硬盘 服务等性能,发email的方法) -摘自网络
I have created an alert in Performance Monitor (Windows Server 2008 R2) that should be triggered whe ...
- hdu5773--The All-purpose Zero(LIS变形)
题意:给一个非负整数的数列,其中0可以变成任意整数,包括负数,求最长上升子序列的长度. 题解:LIS是最简单的DP了,但是变形之后T^T真的没想到.数据范围是10^5,只能O(nlogn)的做法,所以 ...
- A Tour of Go Interfaces are satisfied implicitly
A type implements an interface by implementing the methods. There is no explicit declaration of inte ...
- 表单,css
- Java foreach操作(遍历)数组
语法: 我们分别使用 for 和 foreach 语句来遍历数组 运行结果: 练习: import java.util.Arrays; public class HelloWorld { public ...
- JavaScript要点(九)HTML DOM
通过 HTML DOM,可访问 JavaScript HTML 文档的所有元素. HTML DOM (文档对象模型) 当网页被加载时,浏览器会创建页面的文档对象模型(Document Object M ...
- Java数据类型(一)
1 public class VarDemo 2 { 3 public static void main(String []args){ 4 //先声明后赋值 5 int number; 6 numb ...
- jquery判断输入文字个数的统计代码
1.js代码部分 <script type="text/javascript"> $(function() { function albumNa ...
- C#-动态生成40个按钮,大小(20,20),要求每行6个放置
应该为for (int i=0;i<基本数据DataSet3.Tables [0].Rows .Count ;i++) { int ...