前两年看书的时候,了解到了面向切面编程方法(AOP)。对这个技术印象最深刻的特点就是可以实现业务逻辑和权限、异常处理等的分离。正好在做项目的时候,有些场景可以借鉴这个思想,于是在项目中借用开源的.net环境的KingAOP实现了菜单按钮权限控制、上下游节点的状态控制,效果还不错。
AOP介绍
网上查了一些资料,AOP已经发展很长时间,应该是个比较成熟的技术,在java Spring框架中貌似应用很普遍。
具体可以实现的功能如下:(参考百度百科)
- Authentication 权限
- Caching缓存
- Context passing内容传递
- Error handling 错误处理
- Lazy loading 延时加载
- Debugging 调试
- logging, tracing, profiling and monitoring 记录跟踪 优化 校准
- Performance optimization性能优化
- Persistence 持久化
- Resource pooling资源池
- Synchronization 同步
- Transactions事务
.net AOP工具
网上查了很多资料,发现.net平台下框架不多,而且收费,比如PostSharp,Spring .net。一开始找了PostSharp试用,发现框架太重,还不容易上手。又搜索了其他一些框架,找了一款开源的.net AOP框架,叫KingAOP。我觉得框架很轻,源码中带着几个例子,非常容易上手,满足项目上的需要,于是决定使用KingAOP实现项目中菜单按钮权限管理和节点状态控制功能。
AOP实现
项目介绍
本项目是一个CAE二次开发项目,目的是基于ANSYS搭建用于核电分析法设计计算的平台。该项目之前,还有一个相同需求的项目,也是我主导实施的。当时,我们完全在ANSYS内部做二次开发实现的。这种开发方法使用TCl/Tk和C#混合的方法实现,效率很慢,而且不稳定。
基于本项目,我们想搭建一个框架,将经典ANSYS嵌入到框架中,希望以后所有的ANSYS二次开发项目都能使用这个框架来实现,节省成本,提高效率。
借用AOP实现的功能
- 项目中涉及到不同人员权限的设置,即不同人员可以使用的菜单按钮是不一样的。
- 前处理、求解、后处理中的各个功能的逻辑关系想通过节点状态的变化反应出来,通过节点状态来控制功能之间的数据逻辑流转。
实现过程
1.测试KingAOP
KingAOP下载后,使用几个例子做测试,发现源码可能有些问题,于是修改了,重新编译得到dll文件。(具体修改的哪里,有点忘了)
2. 编写权限验证代码
以该项目为例,我们实现了使用授权文件进行权限验证的功能:
- 编写了一个LicenseManager类,用来管理权限相关内容
- 编写了一个static bool LicenseValid(string licName)函数,用来验证权限;
3. 套上AOP外套
继承KingAOP的 MethodInterceptionAspect,实现基于权限管理的控制:
public class licenseManageAspect : MethodInterceptionAspect
{
public override void OnInvoke(MethodInterceptionArgs args)
{
if (LicenseManager.LicenseValid("./Licensing/license.lic"))
{
...
args.Proceed();
}
else
{
args.ReturnValue = false;
...
}
}
}
4. 封装业务代码
将业务代码重新组装到实现了AOP接口IDynamicMetaObhectProvider类中
internal class licenseIntercept : IDynamicMetaObjectProvider //继承接口
{
...
public DynamicMetaObject GetMetaObject(Expression parameter)
{
return new AspectWeaver(parameter, this);
}
[licenseManageAspect] //在业务代码方法上附加AOP属性
public void popUpSolver()
{
}
[licenseManageAspect]
public void createNewTask()
{
new taskMenus.newTaskForm().ShowDialog();
}
...
}
5.调用业务代码
在高一层业务代码中创建封装AOP业务代码的类的对象,调用即可。
public class menuCallbacks
{
...
dynamic licenseControl = new licenseIntercept(); //创建用AOP方法封装的业务类实例
public void Exit(object o)
{
Application.Exit();
}
public void createNewTask(object ToolStripMenuItem)
{
licenseControl.createNewTask(); // 调用AOP业务类
}
...
总结
使用AOP,将业务逻辑和权限验证代码分离,互相独立,可以统一修改权限验证逻辑,单独去修改每一功能的逻辑实现。