在这个纷繁的社会里面,统一性的特点能够带来很多高效的产出、牢固的记忆,这种特征无论对于企业、个人的开发工作,知识的传承都有着非常重要的作用,Winfrom框架本身就是基于这个理念而生,从统一的数据库设计规则开始,统一的项目格局,统一的业务类、数据访问类、实体类继承关系,再到统一的公用类库,统一的权限管理模块,统一的字典管理模块,统一的附件管理...,理解这些理念和规则后,再来个终极的统一,框架代码快速生成--Database2Sharp代码生成工具。所有的框架(包括传统Winform开发框架、WCF开发框架、混合式开发框架、Web开发框架)都融合到这里来,统一整合各种看似零散,实则高度渗透的模块,统一的步伐除了时间、效力外,带来给我更多的馈赠。本文主要介绍我的Winform框架(也包括其他框架的特点)的业务对象统一调用的方式,介绍如何通过BLLFactory或者CallerFactory的公用类库来实现各种业务对象的创建工作。

1、BLLFactory的对象统一调用规则

在我的框架里面,所有的业务类调用都是以BLLFactory入口进行开始创建,传递业务对象进去即可创建,这种统一入口的方式能够方便记忆,并减少代码,更重要的是能够很好把一些如缓存规则、创建规则封装起来,简化代码。BLLFactory的创建示意图如下所示。

既然是统一调用规则方式,那么BLLFactory的类库就应该提升到公用类库的级别,所以提供Winform框架支持的公用类库如下所示。

当然,为了减少代码,提高开发效率,整体的框架处处体现了代码重用的规则,尽可能把重复的代码提取出来,因此还有很多如数据访问基类、业务访问基类、数据访问基类接口、实体基类等类库,结合泛型能够使我们的API更加统一化、强类型化,提高开发效率。由于BLLFactory是公用类库级别,所有独立开发的模块,也都是以该类库为统一入口,创建所必须的对象。

我们看看框架如何能够在纷繁复杂的类库里面,准确创建一系列的对象的。

BLLFactory业务对象工厂辅助类的代码如下所示。

    /// <summary>
/// 对业务类进行构造的工厂类
/// </summary>
/// <typeparam name="T">业务对象类型</typeparam>
public class BLLFactory<T> where T : class
{
private static Hashtable objCache = new Hashtable();
private static object syncRoot = new Object(); /// <summary>
/// 创建或者从缓存中获取对应业务类的实例
/// </summary>
public static T Instance
{
get
{
string CacheKey = typeof(T).FullName;
T bll = (T)objCache[CacheKey];  //从缓存读取
if (bll == null)
{
lock (syncRoot)
{
if (bll == null)
{
bll = Reflect<T>.Create(typeof(T).FullName, typeof(T).Assembly.GetName().Name); //反射创建,并缓存
objCache.Add(typeof(T).FullName, bll);
}
}
}
return bll;
}
}
}

其中利用了哈希表对象对创建的对象进行缓存,并进一步传递参数给Reflect公用类库,对指定对象全名、程序集的业务对象进行创建。

以上只是很薄的一层关系,一般我们都能够很容易理解,但是我们知道,每个业务对象类,还需要负责创建里面的数据访问基类(如IUser接口的数据访问基类userDal),我们来继续分析BaseBLL对象的工作逻辑,才能很好理解其中的关系。

    /// <summary>
/// 用户信息业务管理类
/// </summary>
public class User : BaseBLL<UserInfo>
{
private IUser userDal; public User() : base()
{
base.Init(this.GetType().FullName, System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
this.userDal = (IUser)base.baseDal;
}
.............................. }

其中Init的函数接口定义如下,主要就是根据相关参数,构建数据不同的数据访问对象,如SqlServer的访问对象,或者Oracle的数据访问对象等。

        /// <summary>
/// 参数赋值后,初始化相关对象
/// </summary>
/// <param name="bllFullName">BLL业务类的全名(子类必须实现),子类构造函数传入this.GetType().FullName</param>
/// <param name="dalAssemblyName">数据访问层程序集的清单文件的文件名,不包括其扩展名,可使用Assembly.GetExecutingAssembly().GetName().Name</param>
/// <param name="bllPrefix">BLL命名空间的前缀(BLL.)</param>
void Init(string bllFullName, string dalAssemblyName, string bllPrefix = "BLL.")

由于数据访问也是基于反射方式(带缓存)创建,因此需要知道数据访问类的全名和对应的程序集,如果整合在一个项目工程里面,如我的框架结构代码所示,那么dalAssemblyName就是System.Reflection.Assembly.GetExecutingAssembly().GetName().Name了。其中Init函数主要就是根据配置的数据库类型,创建指定类型的数据访问业务对象,主要的逻辑代码如下所示。

            #region 根据不同的数据库类型,构造相应的DAL层
AppConfig config = new AppConfig();
string dbType = config.AppConfigGet("ComponentDbType");
if (string.IsNullOrEmpty(dbType))
{
dbType = "sqlserver";
}
dbType = dbType.ToLower(); string DALPrefix = "";
if (dbType == "sqlserver")
{
DALPrefix = "DALSQL.";
}
else if (dbType == "access")
{
DALPrefix = "DALAccess.";
}
else if (dbType == "oracle")
{
DALPrefix = "DALOracle.";
}
else if (dbType == "sqlite")
{
DALPrefix = "DALSQLite.";
}
else if (dbType == "mysql")
{
DALPrefix = "DALMySql.";
}
#endregion this.dalName = bllFullName.Replace(bllPrefix, DALPrefix);//替换中级的BLL.为DAL.,就是DAL类的全名
baseDal = Reflect<IBaseDAL<T>>.Create(this.dalName, dalAssemblyName);//构造对应的DAL数据访问层的对象类

由于BLLFactory<T>通过传入指定的业务对象,成功创建后,会返回相关联的类的实例,因此接口的调用在设计时就知道了,也就是上面例子里面的BLLFactory<BLL.User>.Instance就是BLL.User类的实例,具有所有该类的接口方法,实现了强类型API的目的了。

下面就是该类在实际界面项目里面的使用例子代码。

                try
{
UserInfo info = BLLFactory<User>.FindByID(currentID) as UserInfo;
if (info != null)
{
info = SetUserInfo(info);
BLLFactory<User>.Instance.Update(info, info.ID.ToString());
RefreshTreeView(); MessageDxUtil.ShowTips("资料保存成功");
}
}
catch (Exception ex)
{
LogTextHelper.Error(ex);
MessageDxUtil.ShowError(ex.Message);
}

2、CallerFactory的对象统一调用规则

CallerFactory对象是用于创建基于Facade层接口的业务对象,主要用在我的WCF开发框架、混合式开发框架里面,该对象的创建逻辑类似于BLLFactory,不过它创建的对象,可能是基于WCF客户代理的对象,也可能是对BLLFactory创建对象的进一步封装,以便实现宏观上的统一。如下图所示,CallerFactory处在下面框架结构图的中间部分,UI层的下面。

CallerFactory的调用代码例子如下所示。

                {
UserInfo info = CallerFactory<IUserService>.Instance.FindByID(currentID);
if (info != null)
{
info = SetUserInfo(info);
CallerFactory<IUserService>.Instance.Update(info, info.ID.ToString());
RefreshTreeView(); MessageDxUtil.ShowTips("资料保存成功");
}
}
catch (Exception ex)
{
LogHelper.Error(ex);
MessageDxUtil.ShowError(ex.Message);
}

我们看到,虽然上面的代码是基于WCF的分布式应用,我们还是可以看到,这个调用的思路和方式,和传统Winform的BLLFactory如出一辙,能解决对象调用问题的同时,这样的操作方式,能够给我们学习框架提供了更好的统一模式,顺利切换,而且,从传统Winfrom开发框架的界面代码迁移到分布式应用的WCF开发上,界面代码的变化也是很有规律的,这就是统一模式的力量和奥妙所在。

和BLLFactory里面传入的业务层对象不同,这里CallerFactory里面传入的对象是Facade层的接口,那么它是如何知道我们要创建的对象,并把它转换为我们需要的接口的呢?

    /// <summary>
/// 混合式框架或WCF框架中针对不同调用方式的工厂类(WCF或者Win调用)
/// </summary>
/// <typeparam name="T">接口类型</typeparam>
public class CallerFactory<T>
{
private static Hashtable objCache = new Hashtable();
private static object syncRoot = new Object();
private static string callerNamespace = null;//Facade接口实现类的命名空间 /// <summary>
/// 创建或者从缓存中获取对应接口的实例
/// </summary>
public static T Instance
{
get
{
string CacheKey = typeof(T).FullName;
T bll = (T)objCache[CacheKey];  //从缓存读取
if (bll == null)
{
lock (syncRoot)
{
if (bll == null)
{
bll = CreateObject(); //反射创建,并缓存
if (bll != null)
{
objCache.Add(typeof(T).FullName, bll); //缓存BLL业务对象
}
}
}
}
return bll;
}
}

从上面的代码我们看到,这里的创建逻辑和BLLFactory很大程度的相同,只是细节部分,我使用了CreateObject 进行了隔离,放到独立的函数里面进行创建了。

CreateObject 函数主要逻辑就是根据WCF框架配置信息,到具体的程序集里面创建对应的对象实例,然后转换为Facade层接口,方便统一调用。这就是我WCF开发框架和混合式开发框架,统一调用接口进行通讯获取或提交数据的工作模式。

以上就是我Winform开发框架、WCF开发框架、混合式开发框架、Web开发框架里面所用到的两种方式的对象创建方式的说明,希望您能从统一的调用方式可以看到更多的奥妙及好处。

关于以上几种框架的定义说明,请查看下面图示的介绍,打开图示可以查看更多的框架介绍内容。

Winform开发框架的业务对象统一调用方式的更多相关文章

  1. Winform开发框架之通用Windows摄像头调用拍照--SNF快速开发平台3.3-Spring.Net.Framework

    今天做了一个windows系统下调用摄像头.进行开启.关闭.拍照.设置等等功能演示. 进行源码贡献,欢迎大家下载使用 一.DEMO效果如下: 二.DEMO演示代码如下: using SNF.Utili ...

  2. Winform开发框架中实现多种数据库类型切换以及分拆数据库的支持

    在很多应用系统里面,虽然一般采用一种数据库运行,但是由于各种情况的需要,可能业务系统会部署在不同类型的数据库上,如果开发的系统能够很方便支持多种数据库的切换,那可以为我们减少很多烦恼,同时提高系统的适 ...

  3. Winform开发框架重构总结

    最近一直致力于Winform开发框架的重构工作,因为发现要维护传统Winform开发框架.WCF开发框架.混合式开发框架,以及相关的模块,包括权限管理.字典管理模块.附件管理.人员管理等一些辅助模块, ...

  4. Winform开发框架之存储过程的支持--存储过程的实现和演化提炼(2)

    本篇继续上篇<Winform开发框架之存储过程的支持--存储过程的实现和演化提炼(1)>来对Winform开发框架之存储过程的支持进行介绍,上篇主要介绍了SQLServer和Oracle两 ...

  5. Winform开发框架之权限管理系统改进的经验总结(4)-一行代码实现表操作日志记录

    在前面介绍了几篇关于我的权限系统改进的一些经验总结,本篇继续这一系列主体,介绍如何一行代码实现重要表的操作日志记录.我们知道,在很多业务系统里面,数据是很敏感的,特别对于一些增加.修改.删除等关键的操 ...

  6. Winform开发框架的重要特性总结

    从事Winform开发框架的研究和推广,也做了有几个年头了,从最初的项目雏形到目前各种重要特性的加入完善,是经过了很多项目的总结归纳和升华,有些则是根据客户需要或者应用前景的需要进行的完善,整个Win ...

  7. Winform开发框架之插件化应用框架实现

    支持插件化应用的开发框架能给程序带来无穷的生命力,也是目前很多系统.程序追求的重要方向之一,插件化的模块,在遵循一定的接口标准的基础上,可以实现快速集成,也就是所谓的热插拔操作,可以无限对已经开发好系 ...

  8. Winform开发框架之权限管理系统的改进

    权限管理系统,一直是很多Mis系统和一些常见的管理系统所需要的,所以一般可以作为独立的模块进行开发,需要的时候进行整合即可,不需要每次从头开发,除非特殊的系统需求.我在Winform开发框架介绍中的随 ...

  9. Winform开发框架中工作流模块之申请单草稿处理

    在我们开发工作流模块的时候,有时候填写申请单过程中,暂时不想提交审批,那么可以暂存为草稿,以供下次继续填写或者提交处理,那么这个草稿的功能是比较实用的,否则对于一些填写内容比较多的申请单,每次要重填写 ...

随机推荐

  1. IT技术团队行而有效的管理之道

    在博客园看到的一份读书笔记,如果日后有机会去管理一个技术团队,那么下面这些经验可能会让你更好地实施工作. IT技术团队员工的特点 高学历,知识密集型,技术立身. 人际关系简单,摩擦大多数由技术产生,相 ...

  2. 39. Volume Rendering Techniques

    Milan Ikits University of Utah Joe Kniss University of Utah Aaron Lefohn University of California, D ...

  3. ffrpc的php客户端lib

    摘要: ffrpc 是c++异步通讯库,使用ffrpc可以非常容易的构建服务器程序.为了使用方便,ffrpc提供了python.php的客户端lib,这样使用php于c++构建的server也是顺手拈 ...

  4. 2015 Android Dev Summit(安卓开发峰会)第一天

    今年的Google I/O没有抽到票,不能到现场参加.不过11月举行的Android Dev Summit的票是先到先得的方式,所以早早的提交了注册.今天终于有机会当面跟Android系统的设计开发者 ...

  5. SQL语句 - 数据操作

    表中数据的变化牵一发而动全身,会同时导致到索引中数据的变化.因此如果查询语句不需要索引,就应该删除无用的索引以提高效率. 一.INSERT语句 1.基本插入语句 insert用于向表中输入数据,其具体 ...

  6. dbvis MySQL server version for the right syntax to use near 'OPTION SQL_SELECT_LIMIT=DEFAULT' at line 1

    转自:http://www.cnblogs.com/_popc/p/4053593.html 今天使用数据库查询工具DBvis链接mysql数据库时, 发现执行如何sql语句, 都报如下错误: 后来想 ...

  7. 基于HTML5的Web跨设备超声波通信方案

    前言:Chirp在iPhone上掀起了有声传输文件的序幕,我们再也不需要彩信.蓝牙配对.IM来传送数据.它通过“叽叽喳喳”的小鸟叫声来分享数据,简单有趣,而且可以快速的实现一对多的分享. 此外支付宝曾 ...

  8. Dennis与Ken爷爷的UNIX/C世界

     沉寂了很久了,时间在不断地逝去,转眼又到了新的一年,2013的发生了太多,Beta版本.辞职.职位转换.ARM.Driver.初级厨艺.Dx11.GPU.CPU.登山.GNU/Linux.Cross ...

  9. SQL设置SQLServer最大连接数查询语句

    设置最大连接数 下面的T-SQL 语句可以配置SQL Server 允许的并发用户连接的最大数目. exec sp_configure 'show advanced options', 1exec s ...

  10. Oracle数据库说明