Welcome

首页 / 软件开发 / .NET编程技术 / 利用EnteLib Unity Interception Extension和PIAB实现Transaction的Call Hand

利用EnteLib Unity Interception Extension和PIAB实现Transaction的Call Hand2011-04-15 博客园 大熊一.写作前提

之前在苏州的一家知名软件企业工作时,使用了他们提供的框架和类库,切实的感受到它 们所带来的便利,它不仅提高了软件的开发速度,减少了代码的冗余,更重要的是提高了企 业产品的开发效率及质量。而今换了工作环境(一家国外小软件公司),在缺少了这些有利 的工具之后,发现公司之前的几乎所有项目都在重复的Copy代码,这不仅仅是延长项目的开 发周期,最麻烦的莫过于对项目的管理借来及大的困难,看了让我心里有些不是滋味。之后 ,我就开始尝试着写些高效、集成的代码(已经写了一部分了),我希望能够和大家分享和 交流,也希望得到一些指正和建议。

本篇我们所要讨论的问题就是如何使用Enterprise Library的Unity Interception Extension 和Policy Injection Application Block(PIAB)实现以Attribute形式注入的 Transaction Call Handler。关于什么是事务,这里就不在多加叙述,我们把更多的篇幅用 来本文的主题进行讲解。

二.将Transaction与业务逻辑分离

Enterprise Library 是微软推出的一个Open Source框架,或者说是一个可扩展的类库, 最新Release版本是4.1,目录已经出了5.0人的Bate版本。Enterprise Library是由多个 Application Block组成的,例如:

Caching Application Block
Data Access Application Block
Exception Handling Application Block
Logging Application Block
Unity Application Block
Validation Application Block
Policy Injection Application Block

Policy Injection Application Block使得开发人员可以使用拦截策略执行一些比较 Common及非业务逻辑的特性,例如:Logging、Caching、Exception、Validation以及其他的 控制与操作,在PIAB中,它们以注入的形式提供给开发者,为用户的开发带来了及大的方便 ,所以我考虑以同样的形式来写了一个injection的Transaction Call Handler,它用来在对 实际方法调用之前进行拦截,然后开启Transaction,调用实际目标方法,最好实现提交 Transaction,并在Transaction中进行相应的扩展操作。

OK,首先我们来看看传统的事务代码:

图1: Traditional Transaction Code

public void AddUser(DataSetUser ds)
{
SqlConnection connection = new SqlConnection();
connection.ConnectionString = ConfigurationManager.ConnectionStrings ["TransactionDemoConnectionString"].ConnectionString;
connection.Open();
SqlTransaction transaction = connection.BeginTransaction();
try
{
SqlCommand command = connection.CreateCommand();
command.Transaction = transaction;
command.CommandType = CommandType.Text;
int i = 0;
foreach (DataSetUser.T_USERRow row in ds.T_USER.Rows)
{
//if (i == 1)
// throw new Exception("Test");
command.CommandText = "insert into T_USER([Name], [Password]) values(@p_username,@p_password)";
command.Parameters.Clear();
command.Parameters.Add(new SqlParameter (@"@p_username", row.Name));
command.Parameters.Add(new SqlParameter (@"@p_password", row.Password));
command.ExecuteNonQuery();
i++;
}
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
}
finally
{
if (connection != null)
connection.Close();
connection.Dispose();
}
}