稳中求进开发WinForm项目(2)–项目代码的解析。循序渐进开发WinForm项目(2)–项目代码的分析。

随笔背景:在多时节,很多入门不久的爱侣都见面问我:我是打外语言转至C#支出之,有无发局部基础性的素材给我们念深造呢,你的框架感觉一下顶要命了,希望有个循序渐进的课程或者视频来学就是哼了。

随笔背景:在过剩时刻,很多入门不久的情侣还见面问我:我是自其它语言转至C#支出之,有无来局部基础性的素材给我们念深造啊,你的框架感觉一下最为怪了,希望发个循序渐进的教程或者视频来学习就是哼了。
实际也许我们每日给的无限多东西了,觉得多且散平常了,即使非常轻之地方,可能咱们都曾经形成习惯了。反过来,如果我们切换至任何世界,如IOS、android,那么开我们恐怕针对其中很多规划之条条框框不甚了解,开始或啊是一头雾水。
本篇继续上等同篇《稳中求进开发WinForm项目(1)
–数据库设计以及花色框架的变更》,继续介绍如何循序渐进开发Winform项目,继续分析介绍Winform的种类代码,从而被我们更加了解其中的分段和项目框架的结合等内容。

实质上也许我们每日对的极端多东西了,觉得多还散平常了,即使非常薄之地方,可能我们还已经形成习惯了。反过来,如果我们切换至任何世界,如IOS、android,那么开我们兴许对里面很多统筹之平整不甚了解,开始容许也是一头雾水。

1、数据访问接口的概念

点我们解析了实体类的定义,本节继续分析任何部分的内容,如数据看接口成的定义如下所示。

namespace WHC.TestProject.IDAL
{
    /// <summary>
    /// 客户信息
    /// </summary>
    public interface ICustomer : IBaseDAL<CustomerInfo>
    {
    }
}

这其间的代码很粗略,没有多余的代码行,那么内部到底生了啊吧,其中的IBaseDAL又是什么概念为?

lovebet爱博体育官网 1

实际上,IBaseDAL就是概念了不少咱出用到之根底接口,如正式的增删改查,以及衍生出的一些别接口,如分页查询,条件查询等接口内容。这个ICustomer就是用来定义有除标准接口不克促成他的事情接口。
IBaseDAL通过传播一个实体类,从而利于于基类接口提供强类型的数据类型指定,提高我们的开效率,减少失误的时机。
我们可以以VS里面查看IBaseDAL的定义,如下所示:

lovebet爱博体育官网 2

好看来里边很多系的接口定义,有返回实体T的,也发出返List<T>的,还有DataTable类型等等,这些基础接口,经过我们差不多单种类的使用实践,已逐步稳定并能提供好好之接口支持,方便我们迅速调用处理。
纵然我们于未曾落实任何工作接口的状下,仅仅用标准的基类API,也差不多会形成绝大多数之多寡操作功能了。

本篇继续上亦然篇《稳中求进开发WinForm项目(1)
–数据库设计与类别框架的转变》,继续介绍如何循序渐进开发Winform项目,继续分析介绍Winform的花色代码,从而为我们越了解其中的分层和类框架的咬合等内容。

2、数据看接口实现类似的定义

咱们分析了IDAL的多少看接口成的概念后,继续了解一下,如何根据这个接口进行访问层的落实规划的。数据访问的实现交汇在档次遭到之职如下所示(以基于SqlServer的DALSQL层进行解析)。

lovebet爱博体育官网 3

它们的类代码定义如下所示。

namespace WHC.TestProject.DALSQL
{
    /// <summary>
    /// 客户信息
    /// </summary>
    public class Customer : BaseDALSQL<CustomerInfo>, ICustomer
    {

数码访问接口实现层和接口定义层一样,都有一个基类,如根据SqlServer实现的基类为BaseDALSQL,这个基于SqlServer的数看基类,它呢是延续自一个特级基类(大多数的落实以此间)AbstractBaseDAL。他们中间的接轨关系如下所示

lovebet爱博体育官网 4

如果我们刚刚在列工的希冀中间来看,BaseDALSQL、IBaseDAL、AbstractBaseDAL这些类库由于拥有非常十分之通用性,为了减小在不同的类被开展复制导致维护问题,因此我们所有管这些经常采取及之基类或者接口,抽取到一个单身的类库里面,为了跟一般的DotNET公用类库命名进行区分(WHC.Framework.Commons),我们拿它们定名为WHC.Framework.ControlUtil。
BaseDALSQL基类的定义如下所示。

lovebet爱博体育官网 5

这么做的裨益是,在富有的模块里面,避免复制导致的本维护问题,同时也缩减代码的再次生成,增量生成的任何代码,可以一次性复制到周项目工程中,而休见面导致基础类库的更迭,因为这些基类不在变化目录中,所有变更的类似公事,都是跟业务表相关的,如下所示。

lovebet爱博体育官网 6

现实的多少访问实现类似(如Customer),它将数据库信息变换为实体类,有一个函数,在代码生成的当儿就成形;同时以将实体类的性质保存到数据库也发生一个类似CRM的映照关系,从而实现可空的字段获取和更新操作。

/// <summary>
/// 将DataReader的属性值转化为实体类的属性值,返回实体类
/// </summary>
/// <param name="dr">有效的DataReader对象</param>
/// <returns>实体类对象</returns>
protected override CustomerInfo DataReaderToEntity(IDataReader dataReader)
{
    CustomerInfo info = new CustomerInfo();
    SmartDataReader reader = new SmartDataReader(dataReader);

    info.ID = reader.GetString("ID");
    info.Name = reader.GetString("Name");
    info.Age = reader.GetInt32("Age");
    info.Creator = reader.GetString("Creator");
    info.CreateTime = reader.GetDateTime("CreateTime");

    return info;
}

/// <summary>
/// 将实体对象的属性值转化为Hashtable对应的键值
/// </summary>
/// <param name="obj">有效的实体对象</param>
/// <returns>包含键值映射的Hashtable</returns>
protected override Hashtable GetHashByEntity(CustomerInfo obj)
{
    CustomerInfo info = obj as CustomerInfo;
    Hashtable hash = new Hashtable(); 

    hash.Add("ID", info.ID);
     hash.Add("Name", info.Name);
     hash.Add("Age", info.Age);
     hash.Add("Creator", info.Creator);
     hash.Add("CreateTime", info.CreateTime);

    return hash;
}

1、数据看接口的定义

地方我们分析了实体类的定义,本节继续分析任何有的情节,如数据访问接口成的概念如下所示。

namespace WHC.TestProject.IDAL
{
    /// <summary>
    /// 客户信息
    /// </summary>
    public interface ICustomer : IBaseDAL<CustomerInfo>
    {
    }
}

即时中的代码很粗略,没有多余的代码行,那么内部究竟出了呀呢,其中的IBaseDAL又是呀概念为?

lovebet爱博体育官网 7

实在,IBaseDAL就是概念了广大我们付出用到的根底接口,如正式的增删改查,以及衍生出的一些旁接口,如分页查询,条件查询等接口内容。这个ICustomer就是用来定义有除标准接口不可知兑现他的作业接口。

IBaseDAL通过传播一个实体类,从而利于给基类接口提供强类型的数据类型指定,提高我们的出效率,减少失误的火候。

咱得以在VS里面查看IBaseDAL的概念,如下所示:

lovebet爱博体育官网 8

足看其中很多相关的接口定义,有归实体T的,也发出归List<T>的,还有DataTable类型等等,这些基础接口,经过我们差不多个种类的用实践,已逐渐平稳并能够提供十分好的接口支持,方便我们很快调用处理。

虽我们于从来不兑现任何业务接口的情形下,仅仅以专业的基类API,也多会完成绝大多数之数量操作功能了。

 

3、业务逻辑层的贯彻分析

剖析好了数额访问层的接口和落实类似后,我们来进一步探业务逻辑层的落实分析,由于数量访问层的本心是根据特定的数据库实现,因此业务逻辑层就是架空不同的数据库,让它们根据部署,指向不同之数据库实现类似,从而实现多数据库的支撑。

namespace WHC.TestProject.BLL
{
    /// <summary>
    /// 客户信息
    /// </summary>
    public class Customer : BaseBLL<CustomerInfo>
    {
        public Customer() : base()
        {
            base.Init(this.GetType().FullName, System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
        }
    }
}

作业逻辑层的代码也蛮粗略,在构造函数里面Init一下即可,之所以采用这Init操作,其实为确定BLL层的政工对象名称及指定在哪个程序集里面进行布局的待,让给基类进行必要之创建工作。

在BaseBLL的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数据访问层的对象类

这般精确构造出的数据库访问访问对象,并将其换为基类接口,那么就算得以BaseBLL类里的基类接口进行调用了。
万一构造业务对象,通过BLLFactory<T>的泛型工厂,更能精确构造出相应的工作对象类,这样构造出的对象有强类型,非常方便使用。

lovebet爱博体育官网 9

如上就是是事情逻辑层,数据访问层以及数据看接口层的计划关系,为了快速开展付出工作,我们终将要用强类型的接口调用,这样可以大大减少出错机会,而回到的基类接口,由于传入了特定的求实类型T,也能组织出强类型的列表或者目标。因此,合理施用泛型,能够是咱们的支付体验更加光明,更加高效。
稳中求进开发WInform项目–密密麻麻文章导引:
稳中求进开发WinForm项目(6)–开发使用混合式Winform模块
稳中求进开发WinForm项目(5)–Excel数据的导入导出操作
稳中求进开发WinForm项目(4)–Winform界面模块的合并应用
稳中求进开发WinForm项目(3)–Winform界面层的型统筹
稳中求进开发WinForm项目(2)–项目代码的分析
稳中求进开发WinForm项目(1)
–数据库设计及类型框架的变更

2、数据看接口lovebet爱博体育官网实现类似的定义

 我们解析了IDAL的数码看接口成的定义后,继续探听一下,如何根据这个接口进行访问层的贯彻统筹的。数据看的落实交汇在档次遭到的职如下所示(以基于SqlServer的DALSQL层开展辨析)。

 lovebet爱博体育官网 10

其的类代码定义如下所示。

namespace WHC.TestProject.DALSQL
{
    /// <summary>
    /// 客户信息
    /// </summary>
    public class Customer : BaseDALSQL<CustomerInfo>, ICustomer
    {

数码看接口实现层和接口定义层一样,都发生一个基类,如基于SqlServer实现之基类为BaseDALSQL,这个基于SqlServer的数量访问基类,它呢是连续自一个超级基类(大多数之贯彻在此处)AbstractBaseDAL。他们之间的接续关系如下所示

lovebet爱博体育官网 11

苟我辈才在路工程的觊觎里看到,BaseDALSQL、IBaseDAL、AbstractBaseDAL这些类库由于拥有非常特别的通用性,为了削减在不同之类型被展开复制导致维护问题,因此我们尽将这些经常采取到的基类或者接口,抽取到一个独门的类库里面,为了和普通的DotNET公用类库命名进行分(WHC.Framework.Commons),我们管其取名也WHC.Framework.ControlUtil。

BaseDALSQL基类的概念如下所示。

lovebet爱博体育官网 12

这么做的利是,在享有的模块里面,避免复制导致的本子维护问题,同时为缩减代码的再次生成,增量生成的上上下下代码,可以一次性复制到全体项目工中,而不见面导致基础类库的交替,因为这些基类不以变化无常目录内,所有变化的类公事,都是跟业务表相关的,如下所示。

lovebet爱博体育官网 13

现实的多少看实现类似(如Customer),它把数据库信息转换为实体类,有一个函数,在代码生成的时候已经变化;同时于将实体类的习性保存至数据库也发生一个接近CRM的映照关系,从而实现可空的字段获取和更新操作。

        /// <summary>
        /// 将DataReader的属性值转化为实体类的属性值,返回实体类
        /// </summary>
        /// <param name="dr">有效的DataReader对象</param>
        /// <returns>实体类对象</returns>
        protected override CustomerInfo DataReaderToEntity(IDataReader dataReader)
        {
            CustomerInfo info = new CustomerInfo();
            SmartDataReader reader = new SmartDataReader(dataReader);

            info.ID = reader.GetString("ID");
            info.Name = reader.GetString("Name");
            info.Age = reader.GetInt32("Age");
            info.Creator = reader.GetString("Creator");
            info.CreateTime = reader.GetDateTime("CreateTime");

            return info;
        }

        /// <summary>
        /// 将实体对象的属性值转化为Hashtable对应的键值
        /// </summary>
        /// <param name="obj">有效的实体对象</param>
        /// <returns>包含键值映射的Hashtable</returns>
        protected override Hashtable GetHashByEntity(CustomerInfo obj)
        {
            CustomerInfo info = obj as CustomerInfo;
            Hashtable hash = new Hashtable(); 

            hash.Add("ID", info.ID);
             hash.Add("Name", info.Name);
             hash.Add("Age", info.Age);
             hash.Add("Creator", info.Creator);
             hash.Add("CreateTime", info.CreateTime);

            return hash;
        }

 

3、业务逻辑层的兑现分析

 分析形成了数额访问层的接口及促成类似后,我们来一发看业务逻辑层的落实分析,由于数量访问层的本心是基于特定的数据库实现,因此业务逻辑层就是抽象不同的数据库,让它们根据部署,指向不同之数据库实现类似,从而实现多数据库的支撑。

namespace WHC.TestProject.BLL
{
    /// <summary>
    /// 客户信息
    /// </summary>
    public class Customer : BaseBLL<CustomerInfo>
    {
        public Customer() : base()
        {
            base.Init(this.GetType().FullName, System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
        }
    }
}

作业逻辑层的代码也蛮粗略,在构造函数里面Init一下即可,之所以采用这Init操作,其实以确定BLL层的事体对象名称以及指定在哪个程序集里面进行结构的消,让给基类进行必要之创造工作。

以BaseBLL的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数据访问层的对象类

诸如此类精确构造出的数据库访问访问对象,并拿其换为基类接口,那么就是可以BaseBLL类里的基类接口进行调用了。

要构造业务对象,通过BLLFactory<T>的泛型工厂,更会规范构造出相应的工作对象类,这样构造出的目标拥有强类型,非常方便使用。

lovebet爱博体育官网 14

上述就是是事情逻辑层,数据看层以及数目看接口层的计划关系,为了快速开展付出工作,我们一定要运强类型的接口调用,这样可以大大减少出错机会,而回到的基类接口,由于传入了特定的实际类型T,也能组织出强类型的列表或者目标。因此,合理采取泛型,能够是咱们的开支体验更加光明,更加迅速。 

 

相关文章