- 浏览: 410074 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (174)
- ajax (2)
- java (4)
- spring (0)
- eclipse (0)
- ejb (0)
- hibernate (2)
- jsf (1)
- c# (13)
- sqlserver (12)
- oracle (1)
- ibatis (3)
- appfuse (0)
- seam (0)
- log4j (0)
- Java2Html (0)
- javascript && html && css (38)
- 英语学习 (1)
- jag (2)
- guice (0)
- warp (0)
- facelets (1)
- struts (0)
- 资源汇聚 (4)
- 打印 (2)
- 热点文章收藏 (2)
- aop/aop.net (3)
- 代码生成器 (1)
- 数据库 (1)
- 开发工具集 (1)
- Erlang (1)
- web services (1)
- acegi (2)
- 存储过程集汇 (1)
- 黑客攻防 (2)
- C/C++ (6)
- wap (1)
- 缓存 分布式 (0)
- 企业库 (3)
- 搜索引擎:Lucene (0)
- 数据安全 (1)
- uml (1)
- 项目管理 (3)
- asp (1)
- SWT/JFACE (3)
- 面试与技巧 (1)
- 程序人生 (1)
- java rcp (2)
- 软件测试 (4)
- 不同应用服务器整合 (1)
- 数据仓库 (2)
- 求职/离职 (1)
- 网站珍藏 (1)
- visual studio 插件 (2)
- IT那些事 (1)
- linux/unix (10)
- windows (1)
- javaMail (1)
- common mail (1)
- tomcat (1)
- java并发/并行 (3)
- emacs (5)
- zookeeper (1)
- hadoop (7)
- 自动运维部署 (8)
- 业界资讯 (1)
最新评论
-
ffshow2006:
有一个有毒啊
两款Access密码破解器 -
nicepulse:
太好了,正好最近我也遇到这类的问题,代理不大正常,刚开始就是重 ...
SQL Server Agent 执行SSIS失败解决方案 -
supersnake:
这个比较喜欢
5款纯div+css制作的弹出菜单(标准且无js) -
cloudgamer:
我也写过一个提示效果
javascript tooltip (网页的提示效果) -
kuchaguangjie:
顶1个,哈哈
获取页面请求参数的JS脚本
AOP已经不是一个什么新名词了,在博客园使用关键字搜索可以查出n多条关于AOP的介绍,这里就不再赘述了。
在Bruce Zhang's Blog里面有很多关于AOP介绍及其在.net下实现研究,总觉得如果什么都从头来写难免有自造轮子的嫌疑,但是目前也没有很成熟的AOP框架让我们能轻松完成基于AOP架构,不过一直以来都在关注的PostSharp开源项目日趋成熟,目前已发布了PostSharp 1.0 (Beta release 3)。即使如此,也还没能到应用到产品上的时候。
前段时间一直在封装一个权限系统,时常为如何给调用方提供一个良好的编程接口烦恼,加之前前段时间考虑的日志、异常接管、事务、缓存等等一些横向组件的架构分析,自然就想用AOP技术实现,但是由于实现难度实在不小作罢;这两天又重新学习研究了PostSharp的架构与实现思想,觉得还是尝试一下,将其融入现有框架;
早在年初就有不少前辈大师就如何使用这个东西撰写过文章,如Q.yuhen的PostSharp - Lightweight Aspect-Oriented System该仁兄下面见解很到位:
和以往基于 Dynamic Proxy 方式与 AOP 解决方案做个比较。
- 由于采用 MSIL Injection,因此静态代码注入的执行效率要高于使用 Reflection Emit。
- 使用 MSBuild Task,使得开发人员可以像使用编译器内置 Attribute 那样使用 AOP。
- 可以拦截任意方法,而 Dynamic Proxy 方式的 AOP 往往采取继承方式来拦截 Virtual 方法。
- 拥有更多的控制权。包括中断执行流程,修改参数和返回值等等。
- 还可以拦截 Field Access、Exception 等操作。
- 无需将对象创建代码改成 "new proxy()",更加透明。
- 可以使用通配符进行多重拦截匹配。
- 静态注入带来的问题更多的是注入代码的质量和调试复杂度。
另外有一老外的Using AOP and PostSharp to Enhance Your CodeAB两部分,相当精彩,本文就是在参考这两篇好文的基础上做的。
我们假设有这么个场景,其实这也是实际业务中很常见的处理方式:有一定单管理模块,具备新增、删除两功能,我们在新增删除的时候必须校验权限,在删除的时候还必须记录日志,出现异常了还必须捕捉并记录异常;
按以前的写法我们可能很麻烦,我们要如此这般的写:
{
public bool Add(string id, string orderName)
{
try
{
if (User.AddEnable)
{
//TODO:新增订单的实现
Console.WriteLine("正在执行新增订单方法的操作,回车继续……");
Console.ReadLine();
Console.WriteLine("您添加订单成功:编号:{0},名称:{1}", id, orderName);
return true;
}
else
{
//
}
}
catch (Exception)
{
//TODO:记录异常的实现
throw;
}
return true;
}
public bool Delete(string id)
{
try
{
if (User.DeleteEnable)
{
//TODO:删除订单的实现
Console.WriteLine("您删除订单成功:编号:{0}", id);
}
else
{
//
}
}
catch (Exception)
{
//TODO:记录异常的实现
throw;
}
return true;
}
这种写的弊端我就不多说了,有很多先驱都阐述过……
我要演示的是采用AOP技术的框架原型实现:
首先我们应该安装PostSharp(一定要安装要不能没办法注入处理代码)
然后我们实现Orders对象
namespace PostSharp.Demo
{
public class Orders
{
[Permission]
[Exception]
public bool Add(string id, string orderName)
{
Console.WriteLine("正在执行新增订单方法的操作,回车继续……");
Console.ReadLine();
Console.WriteLine("您添加订单成功:编号:{0},名称:{1}", id, orderName);
return true;
}
[Logger]
[Permission]
[Exception]
public bool Delete(string id)
{
Console.WriteLine("您删除订单成功:编号:{0}", id);
return true;
}
}
}
当然还要模拟一个用户资格认证
{
/// <summary>
/// 静态的用户对象,用于存放当前登录用户,成员资格
/// </summary>
public static class User
{
private static string _userId;
public static string UserId
{
get { return _userId; }
set { _userId = value; }
}
public static bool AddEnable
{
get
{
return (_userId.ToLower() == "admin");
}
}
public static bool DeleteEnable
{
get
{
return (_userId.ToLower() == "admin");
}
}
}
}
再然后我们实现权限控制方面PermissionAttribute,日志方面LoggerAttribute,异常处理方面ExceptionAttribute……
PermissionAttribute
using PostSharp.Laos;
namespace PostSharp.Demo
{
[Serializable]
[global::System.AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = false)]
public class PermissionAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionEventArgs eventArgs)
{
if (!User.AddEnable)
{
Console.WriteLine("用户:【{0}】没有权限:【{1}】", User.UserId, eventArgs.Method);
eventArgs.FlowBehavior = FlowBehavior.Return;
}
}
}
}
LoggerAttribute
using PostSharp.Laos;
namespace PostSharp.Demo
{
[Serializable]
[global::System.AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = false)]
public sealed class LoggerAttribute : OnMethodInvocationAspect
{
public override void OnInvocation(MethodInvocationEventArgs eventArgs)
{
DateTime time = DateTime.Now;
string log = "时间:{0},操作人员:{1},操作:{2}!";
object[] arg = eventArgs.GetArguments();
log = String.Format(log, time, User.UserId, "删除Id为" + arg[0].ToString() + "的订单!");
System.IO.File.WriteAllText("C:\\Log.Txt", log);
}
}
}
ExceptionAttribute
using PostSharp.Laos;
namespace PostSharp.Demo
{
[Serializable]
[global::System.AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = false)]
public class ExceptionAttribute : OnExceptionAspect
{
public override void OnException(MethodExecutionEventArgs eventArgs)
{
Console.WriteLine("程序出现异常:{0}", eventArgs.Exception.Message);
eventArgs.FlowBehavior = FlowBehavior.Return;
}
}
}
然后再用控制台程序测试下能不能成功
Console.WriteLine("请输入用户名:");
User.UserId = Console.ReadLine();
Console.WriteLine("请输入密码:");
Console.ReadLine();
string id;
LRedo:
Console.WriteLine("请输入您要执行的操作:新增(A),删除(D),退出(X)");
string opt = Console.ReadLine();
if (opt.ToLower() == "a")
{
Console.WriteLine("请输入订单编号:");
id = Console.ReadLine();
Console.WriteLine("请输入订单名称:");
string name = Console.ReadLine();
order.Add(id, name);
}
else if (opt.ToLower() == "d")
{
Console.WriteLine("请输入订单编号:");
id = Console.ReadLine();
order.Delete(id);
}
else if (opt.ToLower() == "x")
{
}
else
{
Console.WriteLine("您的输入不正确,请重新输入!");
goto LRedo;
}
Console.WriteLine("按任意键退出……");
Console.ReadLine();
写完这些我们再反编译一下生成的exe文件,发现里面的Orders成了这模样了,神奇了?
<!---->public class Orders
{
// Methods
static Orders()
{
if (!~PostSharp~Laos~Implementation.initialized)
{
LaosNotInitializedException.Throw();
}
~PostSharp~Laos~Implementation.~targetMethod~1 = methodof(Orders.Add);
~PostSharp~Laos~Implementation.~aspect~1.RuntimeInitialize(~PostSharp~Laos~Implementation.~targetMethod~1);
~PostSharp~Laos~Implementation.~targetMethod~5 = methodof(Orders.Delete);
~PostSharp~Laos~Implementation.~aspect~5.RuntimeInitialize(~PostSharp~Laos~Implementation.~targetMethod~5);
~PostSharp~Laos~Implementation.~targetMethod~4 = methodof(Orders.Delete);
~PostSharp~Laos~Implementation.~aspect~4.RuntimeInitialize(~PostSharp~Laos~Implementation.~targetMethod~4);
~PostSharp~Laos~Implementation.~targetMethod~3 = methodof(Orders.Add);
~PostSharp~Laos~Implementation.~aspect~3.RuntimeInitialize(~PostSharp~Laos~Implementation.~targetMethod~3);
~PostSharp~Laos~Implementation.~targetMethod~2 = methodof(Orders.Delete);
~PostSharp~Laos~Implementation.~aspect~2.RuntimeInitialize(~PostSharp~Laos~Implementation.~targetMethod~2);
}
private bool ~Delete(string id)
{
Console.WriteLine("您删除订单成功:编号:{0}", id);
return true;
}
public bool Add(string id, string orderName)
{
bool ~returnValue~1;
MethodExecutionEventArgs ~laosEventArgs~7;
try
{
object[] ~arguments~6 = new object[] { id, orderName };
~laosEventArgs~7 = new MethodExecutionEventArgs(methodof(Orders.Add, Orders), this, ~arguments~6);
~PostSharp~Laos~Implementation.~aspect~1.OnEntry(~laosEventArgs~7);
if (~laosEventArgs~7.FlowBehavior == FlowBehavior.Return)
{
return (bool) ~laosEventArgs~7.ReturnValue;
}
try
{
Console.WriteLine("正在执行新增订单方法的操作,回车继续……");
Console.ReadLine();
Console.WriteLine("您添加订单成功:编号:{0},名称:{1}", id, orderName);
~returnValue~1 = true;
}
catch (Exception ~exception~2)
{
object[] ~arguments~3 = new object[] { id, orderName };
MethodExecutionEventArgs ~laosEventArgs~4 = new MethodExecutionEventArgs(methodof(Orders.Add, Orders), this, ~arguments~3);
~laosEventArgs~4.Exception = ~exception~2;
~PostSharp~Laos~Implementation.~aspect~3.OnException(~laosEventArgs~4);
switch (~laosEventArgs~4.FlowBehavior)
{
case FlowBehavior.Continue:
goto Label_0145;
case FlowBehavior.Return:
~returnValue~1 = (bool) ~laosEventArgs~4.ReturnValue;
goto Label_0145;
}
throw;
}
Label_0145:
~laosEventArgs~7.ReturnValue = ~returnValue~1;
~PostSharp~Laos~Implementation.~aspect~1.OnSuccess(~laosEventArgs~7);
~returnValue~1 = (bool) ~laosEventArgs~7.ReturnValue;
}
catch (Exception ~exception~5)
{
~laosEventArgs~7.Exception = ~exception~5;
~PostSharp~Laos~Implementation.~aspect~1.OnException(~laosEventArgs~7);
switch (~
相关推荐
PostSharp工具实现AOP 拦截,获取拦截方法的所有参数,并得到所有参数值。
PostSharp-英文论文 博文链接:https://joerong666.iteye.com/blog/189357
vs2010 + postsharp 2.0 AOP DEMO 需要安装 postsharp 2.0
PostSharp使用静态织入方式实现AOP,其连接点非常丰富,使用简单,而且相对其它一些.NET平台上的AOP框架来说,PostSharp较为轻量级,但是功能却一点也不逊色,因此是我比较喜欢的一个AOP框架。更多关于PostSharp的...
[AOP编程框架].Sharpcrafters.PostSharp.v2.0.9.3.Incl.Keygen.and.Patch.REPACK-Lz0.zip
PostSharp 2.0 C# AOP 框架
PostSharp是一个非常优秀的AOP框架,使用上非常方便,功能强大,对目标拦截的方法不需要做什么修改,但现在已经商业化运作 Notes: All vsix files repacked with cracked PostSharp.Compiler.Settings.dll
著名的AOP框架之一,PostSharp3.0,3.0支持vs12应该。文件中包含注册机,可以联网注册。压缩包只有3.0的vsix插件,建议去官网下载最新版的4.0.1使用。另外啰嗦一下,不喜勿碰,下载杀毒,喷子回避,自己悄悄用就好,...
postsharp组件,vs2010中使用,aop亲测可用
AOP in .NET: Practical Aspect-Oriented Programming 296 pages Publisher: Manning Publications; Pap/Psc edition (June 25, 2013) Language: English ISBN-10: 1617291145 ISBN-13: 978-1617291142 ...
Postsharp 是C#最知名的AOP框架, 最初是开源项目,目前已经商业化运作,网络上很难找到源代码,这里提供PostSharp 早起版本的源代码,以供学习。ostSharp是一种Aspect Oriented Programming 面向切面(或面向方面)...
PostSharp.Community.Packer ... 如果使用此加载项,则这两个DLL将作为资源嵌入到MyProject.exe中并从那里加载。 安装 安装NuGet软件包: PM> Install-Package PostSharp.Community.Packer 在获得免费的PostShar
PostSharp 2.1例子。是学习c# AOP编程必备资料。
欢迎使用此PostSharp示例项目集合。 您可以并通过单击代码引用来导航代码,也可以将它们下载到。 项目 描述 方面框架 记录方法调用,包括参数值。 缓存方法调用的结果 将参数值添加到异常详细信息中的调用堆栈...
PostSharp 4.2 用户手册 英文版
本项目基于MVC4、Entity Framework 5.0 实体框架、Autofac IOC容器、Postsharp AOP切面框架、AutoMapper 对象映射框架、javascript模块化管理框架 Seajs、DWZ UI界面框架 等 构建了一个代码结构优秀的开发框架,...
本文讨论AOP中的基本概念,并使用PostSharp在C#应用程序中实现AOP概念。
PostSharp solves this by extending the C# and VB languages with a notion of pattern. It includes ready-made implementations of the most common patterns found in .NET and gives you a framework to ...