Dispose模式的应用实例以及非托管资源的管理方法

大家对Dispose模式都比较熟悉了。相信都可以书写较好的Dispose模式的代码。
 
如下是自己写的一个,开始用起来还不错。到后来需要和其他框架整合使用时,发现一些问题,
比如IBatis中已经OpenConnection,如果我在new ConnectionHelper()时,应该引用已有的数据库连接对象。
但该对象又不应该由我来释放,而是由IBatis来负责释放。

当我们的非托管资源是由其他对象管理,而我们只是借用时,要确保该非托管资源的管理不是我的职责,
我们不应该越权去管理这些非托管资源。

只要记住一条:冤有头,债有主,谁创建的非托管资源就由谁去收拾吧!

因此如下的实现类中增加了一个标示:

        /// <summary>
        /// 标示是否是当前对象的职责去释放非托管资源。本着谁创建谁释放的原则进行设计
        /// </summary>
        private bool fIsMyResponsibilityToDispose = true;

当我们基于其他资源创建该对象时,就把上述标示设置为false.

-----------------------------------------------------------------------------------------------
using System;
using System.Data;
using System.Collections.Generic;

namespace AppleXml
{
    /// <summary>
    /// 数据库连接辅助类
    /// 目前支持SqlServer,Oracle,Excel的处理
    /// </summary>
    public class ConnectionHelper : IConnectionHelper
    {
        private static Dictionary<string, DataBaseVersion> fConnectionVersions = null;
        private static string fDefaultConnectionString = string.Empty;
        private static DataBaseVersion fDefaultDataBaseVersion;
       

        static ConnectionHelper()
        {           
            fConnectionVersions = new Dictionary<string, DataBaseVersion>();
            fDefaultConnectionString = string.Empty;
            fDefaultDataBaseVersion = DataBaseVersion.SqlServer2005;           
        }

        /// <summary>
        /// 获取新的默认的连接串对应的ConnectionHelper对象
        /// </summary>
        /// <returns></returns>
        public static IConnectionHelper GetNewDefaultConnectionHelper()
        {
            if (DataUtility.InvalidString(fDefaultConnectionString))
            {
                throw new Exception("请设置ConnectionHelper.DefaultConnectionString");
            }
            return new ConnectionHelper(fDefaultConnectionString);
        }

        /// <summary>
        /// 测试指定的数据库连接是否有效,成功返回true,否则返回false
        /// </summary>
        /// <param name="connectionString"></param>
        /// <returns></returns>
        public static bool TestConnection(string connectionString)
        {
            IConnectionHelper ch = null;
            try
            {
                ch = new ConnectionHelper(connectionString);
                ch.Connection.Open();
                ch.Connection.Close();
                return true;
            }
            catch
            {
                return false;
            }
            finally
            {
                if (ch != null)
                {
                    ch.Dispose();
                }
            }
        }

        /// <summary>
        /// 测试指定的数据库设置对象是否有效,成功返回true,否则返回false
        /// </summary>
        /// <param name="dbSettingInfo"></param>
        /// <returns></returns>
        public static bool TestConnection(DataBaseSettingInfo dbSettingInfo)
        {
            return TestConnection(dbSettingInfo.GetConnectionString());
        }

        private string fConnectionString = string.Empty;

        private bool fIsInTransaction = false;
        private IDbConnection fConnection = null;
        private IDbTransaction fTransaction = null;

        /// <summary>
        /// 标示是否是当前对象的职责去释放非托管资源。本着谁创建谁释放的原则进行设计
        /// </summary>
        private bool fIsMyResponsibilityToDispose = true;

        /// <summary>
        /// 标记是否已经释放了资源
        /// </summary>
        private bool fHasDispose = false;

       
        /// <summary>
        /// 这个采用默认的连接字符串。(通过静态构造函数从配置文件中取出来的)
        /// </summary>
        public ConnectionHelper()
        {
            if (DataUtility.InvalidString(fDefaultConnectionString))
            {
                throw new DataBaseNotSetDefaultConnectionStringException();
            }
            fConnectionString = fDefaultConnectionString;
            fIsMyResponsibilityToDispose = true;
        }

        /// <summary>
        /// 这个需要自己设置当前的连接字符串,因为有时候会涉及到多个数据库的操作
        /// </summary>
        /// <param name="connectionString"></param>
        public ConnectionHelper(string connectionString)
        {
            if (DataUtility.InvalidString(connectionString))
            {
                throw new Exception("connectionString不能为空");
            }
            fConnectionString = connectionString;
            fIsMyResponsibilityToDispose = true;
        }

        /// <summary>
        /// 根据现有的IDbConnection对象创建ConnectionHelper对象
        /// </summary>
        /// <param name="conn"></param>
        public ConnectionHelper(IDbConnection conn)
        {
            if (conn == null)
            {
                throw new ArgumentNullException("conn");
            }
            fConnection = conn;
            fIsMyResponsibilityToDispose = false;
        }

        /// <summary>
        /// 根据现有的IDbTransaction创建ConnectionHelper对象
        /// </summary>
        /// <param name="trans"></param>
        public ConnectionHelper(IDbTransaction trans)
        {
            if (trans == null)
            {
                throw new ArgumentNullException("trans");
            }
            fConnection = trans.Connection;
            fTransaction = trans;
            fIsInTransaction = true;
            fIsMyResponsibilityToDispose = false;
        }

        /// <summary>
        /// [获取/设置]默认的连接字符串,同时设置数据库的版本
        /// </summary>
        public static string DefaultConnectionString
        {
            get
            {
                return fDefaultConnectionString;
            }
            set
            {
                fDefaultConnectionString = value;
                if (!DataUtility.InvalidString(fDefaultConnectionString))
                {
                    using (IConnectionHelper ch = new ConnectionHelper())
                    {
                        fDefaultDataBaseVersion = DataBaseUtility.GetDataBaseVersion(ch);
                    }
                }
                else
                {
                    throw new DataBaseNotSetDefaultConnectionStringException();
                }
            }
        }

        /// <summary>
        /// [获取]当前连接对象
        /// </summary>
        public IDbConnection Connection
        {
            get
            {
                if (fConnection == null)
                {
                    fConnection = DataBaseUtility.NewConnection(fConnectionString);                   
                }
                return fConnection;
            }
        }

        /// <summary>
        /// [获取]当前事务对象
        /// </summary>
        public IDbTransaction Transaction
        {
            get
            {
                return fTransaction;
            }
        }

        /// <summary>
        /// [获取]是否正在事务中运行,true表示是,false表示否
        /// </summary>
        public bool IsInTransaction
        {
            get
            {
                return fIsInTransaction;
            }
        }

        /// <summary>
        /// [获取]数据库类型
        /// </summary>
        public DataBaseType DataBaseType
        {
            get
            {
                return DataBaseUtility.GetDataBaseType(Connection);
            }
        }

        /// <summary>
        /// [获取]数据库版本
        /// </summary>
        public DataBaseVersion DataBaseVersion
        {
            get
            {
                if (!fConnectionVersions.ContainsKey(fConnectionString))
                {
                    fConnectionVersions.Add(fConnectionString, DataBaseUtility.GetDataBaseVersion(this));
                }
                return fConnectionVersions[fConnectionString];
            }
        }

        /// <summary>
        /// [获取]当前数据库参数化时前缀的字符,比如Sql的@,Oracle的:
        /// </summary>
        public string ParameterPrefix
        {
            get
            {
                return DataUtility.GetParameterPrefix(this);
            }
        }

        /// <summary>
        /// [获取]当前数据库有效对象名的左边界
        /// </summary>
        public string ObjectLeftMark
        {
            get
            {
                switch (DataBaseType)
                {
                    case DataBaseType.SqlServer:
                        return "[";
                }
                return string.Empty;
            }
        }

        /// <summary>
        /// [获取]当前数据库有效对象名的右边界
        /// </summary>
        public string ObjectRightMark
        {
            get
            {
                switch (DataBaseType)
                {
                    case DataBaseType.SqlServer:
                        return "]";
                }
                return string.Empty;
            }
        }

        /// <summary>
        /// 准备开始事务,如果开始成功返回true,否则false
        /// </summary>
        /// <returns></returns>
        public bool BeginTransaction()
        {
            return BeginTransaction(IsolationLevel.ReadCommitted);
        }

        /// <summary>
        /// 准备开始事务,如果开始成功返回true,否则false,可以指定隔离级别
        /// </summary>
        /// <returns></returns>
        public bool BeginTransaction(IsolationLevel level)
        {
            if (fIsInTransaction)
            {
                return false;
            }
            DataUtility.OpenConnection(Connection);
            fTransaction = Connection.BeginTransaction();
            fIsInTransaction = true;
            return true;
        }

        /// <summary>
        /// 回滚事务,成功 返回true
        /// </summary>
        /// <returns></returns>
        public bool RollbackTransaction()
        {
            if (fIsInTransaction)
            {
                if (fTransaction != null)
                {
                    fTransaction.Rollback();
                }
                fIsInTransaction = false;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 提交事务,成功 返回true
        /// </summary>
        /// <returns></returns>
        public bool CommitTransaction()
        {
            if (fIsInTransaction)
            {
                if (fTransaction != null)
                {
                    fTransaction.Commit();
                }
                fIsInTransaction = false;
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 终结器,在用户忘记时,调用之
        /// </summary>
        ~ConnectionHelper()
        {
            Dispose(false);
        }

        public void Close()
        {
            Dispose();
        }

        /// <summary>
        /// 用户调用的处理。
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 一般在派生类中调用,不是当前对象的职责或者已经释放过了,则不需要再次释放
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {
            //不是当前对象的职责或者已经释放过了,则不需要再次释放
            if (!fIsMyResponsibilityToDispose || fHasDispose)
            {
                return;
            }

            if (disposing)
            {
                //用户调用时的处理
                if (fTransaction != null)
                {
                    fTransaction.Dispose();
                    fTransaction = null;
                }
                if (fConnection != null)
                {
                    fConnection.Close();
                    fConnection = null;
                }
            }
           
            fHasDispose = true;
        }

        /// <summary>
        /// [获取]数据库帮助类。采用这里的帮助对象可以获得最大限度的缓存效果
        /// </summary>
        public IDataBaseHelper DataBaseHelper
        {
            get
            {
                IDataBaseHelper dbh = new DataBaseFactory();
                return dbh;
               
            }
        }

        /// <summary>
        /// 获取安全的对象名(包括表、字段等,比如SqlServer则用[]括起来)
        /// </summary>
        /// <param name="objectName"></param>
        /// <returns></returns>
        public string GetSafetyObjectName(string objectName)
        {
            if (DataUtility.InvalidString(objectName))
            {
                throw new Exception("数据库对象名称不能为空");
            }
            objectName = objectName.Trim();
            if (objectName.StartsWith("[") && objectName.EndsWith("]"))
            {
                return objectName;
            }

            return string.Format("{0}{1}{2}", ObjectLeftMark, objectName, ObjectRightMark);
        }
    }
}

转载于:https://www.cnblogs.com/AppleXml/archive/2008/03/08/1096749.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值