一种基于.Net 2.0的另类AOP

原创 2006年05月31日 23:08:00

说这种方法是AOP其实有些牵强,只能说是多少带出了一点面向切面编程的影子。不过它的实现方法很简洁,不需要任何复杂的库的支持,唯一需要的就是C# 2.0,使用的关键技术是泛型编程和匿名委托。
我的需求是这样的:比如有一个函数,要从一个配置中取得一个整数值:
int GetIntValue()
{
  try
  {
    return Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["SomeSetting"]);
  }
  catch
  {
    return 20;
  }
}
这里涉及了以下几点问题:
1 方法从一个配置文件中读取值,这个值在配置文件中也许不存在
2 也许在配置文件中存在,但它却不是一个有效的整数
3 基于1、2,需要为它做异常处理
4 当异常发生时,需要为它取一个缺省值
也许我要从配置文件里取很多值,涉及到各种类型,或者是从别处取值,但也涉及到类型转换等需要异常处理的情况,这时我们发现,这里“异常处理”成了这类方法的一个“方面”,如果使用AOP的方法,应该对这类方法进行拦截,并进行统一的异常处理。
利用C#2.0,我们可以把这个拦截工作变得很简单。
第一步,让它支持异常处理:
我们来定义一个统一的方法,使它可以进行异常处理:
public T GetValue<T>()
{
  try
  {
    return SomeMethod()
  }
  catch
  {}
}
这里我们使用了C#2.0的泛型特性,使它可以返回任何类型的结果,并且带有编译时类型安全检查,不像C# 1.x那样,返回一个object,仍需要检查object的类型,特别是对于简单类型,如int,则免去了装箱过程。
但这个方法有个很明显的问题,就是当异常发生时,catch的部分并没有返回值,从而导致它编译不能通过。注意到当发生异常时应该返回一个缺省值,而缺省值和返回值的类型必然是相同的,所以可以为它添加一个参数作为缺省值:
第二步,添加缺省值:
public T GetValue<T>(T defaultValue)
{
  try
  {
    return SomeMethod()
  }
  catch
  {
    return defaultValue;
  }
}
我想你早就提出了一个问题,那就是代码中的“SomeMethod”是什么呢?从逻辑上讲这里应该是我们真正要取得想要的值的地方,而取值的办法是随需求而变化的,最佳的处理方式就是留给程序员自己来实现,那么要实现这种操作,最合适的方法就是使用委托(delegate)了:
第三步 加入委托:
public delegate T GetValueDelegate<T>();
public T GetValue<T>(GetValueDelegate<T> dele, T defaultValue)
{
  try
  {
    return dele();
  }
  catch
  {
    return defaultValue;
  }
}
这里委托也使用了泛型,使得它只能返回和我们需要的类型相一致的变量。
这回看着舒服多了。但用过C# 1.x的人都知道delegate那冗长的语法是多么的烦人,并且还有一个问题,就是如果在取值的过程中需要从外界取参数,而参数的个数、类型都是不确定的,那么这个delegate这样定义还合适吗?要不要像C# 1.X那样,定义一个object[]作为参数呢?答案是不必的,因为C# 2.0中我们可以使用匿名委托,并且在匿名委托中我们可以方便的使用它的父作用域中的变量,就像使用本地的变量一样:
第四步,使用我们的AOP:
  int myValue = GetValue(delegate() {
    return Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["SomeSetting"]);
  }, 20);
这里已经通过参数20可以推断出模板参数T的类型,所以不需要再指定模板参数了。现在再使用的时候完全可以不必处理try...catch烦人的语法,只管去取值就可以了 :)

类似的应用还可以在访问数据库时。例如用DataReader访问数据库,必须要刻用完了Reader和Connection需要关闭,并且需要处理各种异常情况。用类似的方法可以写出比较方便的函数:

public delegate T TryExecuteReaderDelegate<T>(SqlDataReader reader);
public T TryExecuteReader<T>(SqlCommand command, TryExecuteReaderDelegate dele, T defaultValue)
{
command.Connection = conn;
SqlDataReader reader = null;
try
{
conn.Open();
reader = command.ExecuteReader();
return dele(reader);
}
catch
{
return defaultValue;
}
finally
{
if(reader != null && !reader.IsClosed)
reader.Close();
if(conn != null && conn.State != ConnectionState.Closed)
conn.Close();
}
}

使用:
SqlCommand command = new SqlCommand("select xxxx");
command.Parameters.AddWithValue("@paramName", value);
String s = TryExecuteReader(command, delegate(SqlDataReader reader)
{
reader.Read();
return reader.GetString(0);
}, "haha");

这样一来,使用的时候要方便很多,再也不用考虑连接是否关闭、是否处理了异常情况等问题:正常的时候返回想要的结果,异常的时候返回缺省值。

在ASP.NET Core中使用AOP来简化缓存操作

前言 关于缓存的使用,相信大家都是熟悉的不能再熟悉了,简单来说就是下面一句话。 优先从缓存中取数据,缓存中取不到再去数据库中取,取到了在扔进缓存中去。 然后我们就会看到项目中有类似这...
  • sD7O95O
  • sD7O95O
  • 2017年11月08日 00:00
  • 189

PTA_6-4 另类堆栈(15 分)_单指针栈

6-4 另类堆栈(15 分) 在栈的顺序存储实现中,另有一种方法是将Top定义为栈顶的上一个位置。请编写程序实现这种定义下堆栈的入栈、出栈操作。如何判断堆栈为空或者满? 函数接口定义:bool P...
  • jianbagengmu
  • jianbagengmu
  • 2017年11月27日 14:02
  • 149

(收藏).NET下的一些AOP框架介绍

原帖:http://www.tech-q.cn/redirect.php?tid=2096&goto=lastpost   AOP引 擎 SetPointSetPoint是一款.NET框 架下的全功 ...
  • u011387207
  • u011387207
  • 2013年07月24日 11:02
  • 2931

.Net AOP(五) 各种IoC框架下实现AOP

.Net AOP(五) 各种IoC框架下实现AOP 首先介绍几种笔者常见的IOC框架 Unity:微软patterns&practicest团队开发的IOC依赖注入框架,支持AOP横切关注点。...
  • liming850628
  • liming850628
  • 2016年03月27日 11:45
  • 6837

【.NET】AOP思想下的日志功能

AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programming,面向对象编程)的补充和完善。      ...
  • zhuanzhe117
  • zhuanzhe117
  • 2015年01月23日 20:22
  • 3490

.Net中的AOP系列之《方法执行前后——边界切面》

PostSharp的边界方法
  • wyqlxy
  • wyqlxy
  • 2017年04月01日 11:01
  • 772

C# 用Attribute实现AOP事务

前言      使用Attribute来实现方法级别事务一直是我的梦想,浅谈Attribute [C# | Attribute | DefaultValueAttribute]有体现我的无奈,Att...
  • fhzh520
  • fhzh520
  • 2015年11月17日 13:59
  • 691

.net利用Attribute简单实现AOP

近日在学AOP,前一篇文章是基于透明代理/真实代理实现的,(前文参考链接:http://blog.csdn.net/jiujiu28/article/details/43562909),但是每次实现A...
  • jiujiu28
  • jiujiu28
  • 2015年02月07日 12:40
  • 1962

.NET平台下的依赖注入(IOC)和 面向切面(AOP)相结合简洁实用的使用方式

近日, 学习.NET平台下的依赖注入(IOC)和 面向切面(AOP)。 力求获得一种简洁实用的方法实现IOC和AOP相结合的使用方式。 查阅了多个技术资料。经过多次测试,基本达到目的。 IOC使...
  • peiyu_peiyu
  • peiyu_peiyu
  • 2013年02月20日 16:18
  • 1439

另类数据Alternative Data行业调查

Alternative Data行业调查 1. 另类数据的定义: “Alternative data in finance refers to any data that is not tradi...
  • Richard_More
  • Richard_More
  • 2016年11月15日 00:08
  • 822
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一种基于.Net 2.0的另类AOP
举报原因:
原因补充:

(最多只允许输入30个字)