PostSharp 使用IL静态注入实现AOP,
下面例子对登录操作进行静态注入,使用Web application ,记录每次登录
PostSharp的使用方法很简单,将自定义的属性 LoggerTrace直接加在需要注册的方法上就可以(事件是特殊的方法)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using PostSharpLogger;
namespace PostSharpWebForm.Account
{
public partial class Login : Page
{
[LoggerTrace]
protected void Page_Load(object sender, EventArgs e)
{
try
{
RegisterHyperLink.NavigateUrl = "Register";
OpenAuthLogin.ReturnUrl = Request.QueryString["ReturnUrl"];
var returnUrl = HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"]);
if (!String.IsNullOrEmpty(returnUrl))
{
RegisterHyperLink.NavigateUrl += "?ReturnUrl=" + returnUrl;
}
}
catch (Exception)
{
throw;
}
finally
{
Response.Write("Hi ^<>^");
}
}
protected void Page_Load2(object sender, EventArgs e)
{
RegisterHyperLink.NavigateUrl = "Register";
OpenAuthLogin.ReturnUrl = Request.QueryString["ReturnUrl"];
var returnUrl = HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"]);
if (!String.IsNullOrEmpty(returnUrl))
{
RegisterHyperLink.NavigateUrl += "?ReturnUrl=" + returnUrl;
}
}
}
}
下面是 创建的自定义属性,具体用法可以查看PostSharp的文档
using PostSharp.Aspects;
using System;
namespace PostSharpLogger
{
[Serializable]
public class LoggerTraceAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
WriteLog.Log(string.Format("Before Entering {0}.{1}.", args.Method.DeclaringType.FullName, args.Method.Name));
args.ReturnValue = "I'm onEntry";
}
public override void OnSuccess(MethodExecutionArgs args)
{
WriteLog.Log(string.Format("Before Entering {0}.{1}.", args.Method.DeclaringType.FullName, args.Method.Name));
}
public override void OnExit(MethodExecutionArgs args)
{
WriteLog.Log(string.Format(" After Entering {0}.{1}.", args.Method.DeclaringType.FullName, args.Method.Name));
args.ReturnValue = args.MethodExecutionTag;
args.FlowBehavior = FlowBehavior.Return;
}
public override void OnException(MethodExecutionArgs args)
{
WriteLog.Log(string.Format("Error Entering {0}.{1}.", args.Method.DeclaringType.FullName, args.Method.Name));
}
}
}
编译Web application 之后,使用 ILSpy查看 Web application的DLL
被注入的方法编译后变成:
using PostSharp.Aspects;
using PostSharp.Aspects.Internals;
using PostSharp.ImplementationDetails_c77a9d44;
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace PostSharpWebForm.Account
{
public class Login : Page
{
protected HyperLink RegisterHyperLink;
protected OpenAuthProviders OpenAuthLogin;
protected void Page_Load(object sender, EventArgs e)
{
MethodExecutionArgs methodExecutionArgs = new MethodExecutionArgs(this, new Arguments<object, EventArgs>
{
Arg0 = sender,
Arg1 = e
});
MethodExecutionArgs arg_27_0 = methodExecutionArgs;
MethodBase = <>z__a_1._1;
arg_27_0.Method = ;
<>z__a_1.a0.OnEntry(methodExecutionArgs);
if (methodExecutionArgs.FlowBehavior != FlowBehavior.Return)
{
try
{
try
{
this.RegisterHyperLink.NavigateUrl = "Register";
this.OpenAuthLogin.ReturnUrl = base.Request.QueryString["ReturnUrl"];
string returnUrl = HttpUtility.UrlEncode(base.Request.QueryString["ReturnUrl"]);
if (!string.IsNullOrEmpty(returnUrl))
{
HyperLink expr_A4 = this.RegisterHyperLink;
expr_A4.NavigateUrl = expr_A4.NavigateUrl + "?ReturnUrl=" + returnUrl;
}
}
catch (Exception)
{
throw;
}
finally
{
base.Response.Write("Hi ^<>^");
}
<>z__a_1.a0.OnSuccess(methodExecutionArgs);
}
catch (Exception exception)
{
methodExecutionArgs.Exception = exception;
<>z__a_1.a0.OnException(methodExecutionArgs);
switch (methodExecutionArgs.FlowBehavior)
{
case FlowBehavior.Default:
case FlowBehavior.RethrowException:
IL_11E:
throw;
case FlowBehavior.Continue:
methodExecutionArgs.Exception = null;
return;
case FlowBehavior.Return:
methodExecutionArgs.Exception = null;
return;
case FlowBehavior.ThrowException:
throw methodExecutionArgs.Exception;
}
goto IL_11E;
}
finally
{
<>z__a_1.a0.OnExit(methodExecutionArgs);
}
}
}
protected void Page_Load2(object sender, EventArgs e)
{
this.RegisterHyperLink.NavigateUrl = "Register";
this.OpenAuthLogin.ReturnUrl = base.Request.QueryString["ReturnUrl"];
string returnUrl = HttpUtility.UrlEncode(base.Request.QueryString["ReturnUrl"]);
if (!string.IsNullOrEmpty(returnUrl))
{
HyperLink expr_5F = this.RegisterHyperLink;
expr_5F.NavigateUrl = expr_5F.NavigateUrl + "?ReturnUrl=" + returnUrl;
}
}
[CompilerGenerated]
static Login()
{
<>z__a_1.Initialize();
}
}
}
原有的方法被加载一个try catch 中