关注开源代码的实际应用
PostSharp4ViewState是PostSharp的一个插件,用于简化Asp.Net页面与控件的状态管理。如果需要将页面或控件中的 字段或属性值保存在ViewState或ControllState中,以便在页面Postback后仍可取得,只需在相应的字段或属性上添加 PersistAttribute特性的声明。
PostSharp4ViewState的主要组件为一个用于搜寻声明了PersistAttribute的字段和属性的AdviceProvider,对于搜寻到字段和属性以如下方式进行织入:
如果字段或属性被配置为存储于ViewState,则创建或修改LoadViewState与SaveViewState;如果字段或属性被配置为存储于 ControlState,则创建或修改 LoadControlState与SaveControlState,同时如果没有OnInit方法则创建一个同时添加 Page.RegisterRequiresControlState(this)调用。
处理ViewState 与 ControlState 存储的方法除了名称不同外其它的都一样,并按以下进行代码生成:
If Save*State method exists new code is added after existing. It stores values of decorated fields/properties in object[] array and puts it together with resut of existing code in another object[] array
If Save*State method doesn't exist it is generated as if it existed and contained only a call to base.Save*State
If Load*State method exists new code is added before existing. It casts passed value to object[] array and uses second element (casted as another object[]) to initiate decorated fields/properties. First value is passed to existing code
If Load*State method does't exist it is generated as if it existed and contained only a call to base.Load*State
例子:
- public class Properties : BaseControl
- {
- private int _intValue;
- [Persist(Mode = PersistMode.ControlState)]
- public int IntProp
- {
- get { return _intValue; }
- set { _intValue = value; }
- }
- }
相应编译后的内容为:
- public class Properties : BaseControl
- {
- private int _intValue;
- protected override void LoadControlState(object A_1)
- {
- object[] ~tmp~0 = (object[]) A_1;
- object[] ~tmp2~1 = (object[]) ~tmp~0[1];
- if (~tmp2~1[0] != null)
- {
- this.IntProp = (int) ~tmp2~1[0];
- }
- A_1 = ~tmp~0[0];
- base.LoadControlState(A_1);
- }
- protected override void OnInit(EventArgs A_1)
- {
- this.Page.RegisterRequiresControlState(this);
- base.OnInit(A_1);
- }
- protected override object SaveControlState()
- {
- object ~tmpOldValue~1 = base.SaveControlState();
- object[] ~tmp~0 = new object[] { this.IntProp };
- return new object[] { ~tmpOldValue~1, ~tmp~0 };
- }
- [Persist(Mode=PersistMode.ControlState)]
- public int IntProp
- {
- get
- {
- return this._intValue;
- }
- set
- {
- this._intValue = value;
- }
- }
- }
由于是编译期代码生成,只是在编译结果中插入用于存储属性值的代码,所以PostSharp4ViewState代码性能与手写代码性能一样。可以通过Reflector反编译结果程序集来进行检查。
PostSharp是一个开放的开台,开发人员可以编写插件或扩展来增强PostSharp。
1、PostSharp4ViewState 自动管理ASP.NET控件的状态,只需在控件的字段或属性上声明一个自定义Attribute就可进行值的存储,并可控制存储在ViewState还是在ControlState。详细介绍
2、PostSharp4EntLib 组合了Enterprise Library Policy Injection与编译时织入而Remoting Proxyies限制的优点
3、Software Transactional Memory 使得程序可以像使用传统数据库的事务一样处理内存中的数据。使用隐乐观锁(implicit optimistic locking),支持嵌套事务。
4、PostSharp4Spring PostSharp与Spring.net的简单整合
5、Entity Framework Bindings 想要使用Microsoft Entity Framework却又讨厌那些编写僵硬的代码?有了PostSharp4ET就可以通过PostSharp生成代码。作者:Ruurd Boeke
6、Log4PostSharp 将 log4net封装成一个简单的自定义Attribute(在MSIL层面生成优化过的IL指令)。trace your programs using a single custom attribute. Log4PostSharp emits optimal instructions for you. Yes, just like hand-tuned code!
7、Build to Manage for .NET 一个Eclipse项目,可使用IBM的Build to Manage平台生成.NET程序。
8、PostSharp4Unity 使类可配置且无需工厂方法就可使用Unity http://www.codeplex.com/unity,同时旧的构造器仍可用。
9、PostSharpAspNet 使得PostSharp可用在Asp.net项目上。
10、DesignByContract 透明地往类或方法中添加前置条件、后置条件及常量。
用过NHibernte的人都知道需要在每个实体类的public属性前加上virtual关键字,才可以使用NHibernate的延迟加载(Lazy-loading)的功能。大多数情况下,没有谁对这种开发方式有意见,但是在我看来这是一种丑陋的开发方式,并且有时会漏写virtual关键字需要在程序进行时才能通过抛出的异常知道问题所在。这里通过AOP框架Postsharp解决此问题。
1、Postsharp程序集或代码可从http://www.postsharp.org/网站下载。下载“Unsealer”并将“Unsealer.Weaver.dll”与“Unsealer.psplugin”相关文件复制到Postsharp安装目录下Plugins文件夹下。在NHibernate实体类所在项目中引用PostSharp.Public.dll和Unsealer.dll。
2、两种方式任选一种:①在每个实体类前加上[Unseal]特性;②在AssemblyInfo.cs文件中加上[assembly: Unseal(AttributeTargetTypes = "*")]。
这样就无需再为NHibernate实体类属性加上virtual了。
注:通过此种方式定义实体类时,任何实体类不可定义为sealed类型。
一篇转自http://www.rainsts.net/article.asp?id=438关于PostSharp的文章。
PostSharp与其它AOP框架一样,可以减少代码行数并且可以改进合乎逻辑的耦合,因此他可以帮助我们建立更稳定、更清洁的设计和更廉价的源代码维 护。与Aspect#、Spring.net之类的AOP框架相比,PostSharp更容易入门并掌握,下面是一个简单的应用范例: