在winform中使用三层架构学习总结

Winform 三层架构小例子

http://www.cnblogs.com/jacky73/archive/2009/09/01/1558083.html
在web开发中常常用到工厂模式三层架构,现在也在Winform中应用这种架构方式,尝试了很多,也模仿了经典例子PetShop,但是还是不行,也参考了网上的一些例子。现在把我这个例子的整个制作过程简单的介绍一下。(由于本例子是介绍三层结构,所以只是简单的应用,如果你觉得这种方式好,请自己实现其他模块)
结构:
-------PMIS--------主程序代码
表示层,负责应用程序的表现形式、用户体验等。
-------DALFactory-----抽象工厂
抽象工厂,用于创建各种数据对象的方法,这里有配置文件和反射的运用。
-------IDAL--------数据接口层(控制是选择什么类型的数据库)
数据操作接口,数据访问层实现其接口并重写它(体现了面向接口的编程思想)。
-------BLL------
处理应用程序的业务逻辑,被表示层调用。
-------Model-------构造模型(对应数据库字段)
Model程序集,存放实体类,用于数据访问层和逻辑层调用
-------SQLServerDAL----SQLServer数据访问层
数据访问层,实现具体的select、update、delete....操作,重写IDAL接口。
-------DBUtility----公共数据访问层
数据处理层,实现具体的ExecuteReader,ExecuteDataTable,ExecuteNonQuery等。
-------Utility----公共层
实现从配置文件中读取数据库联接字符串。
1、数据库结构
数据库名PMIS
表Admin
    [ID] [bigint] 编号
    [Name] [varchar](10) 名称
    [PassWord] [varchar](100) 密码
    略......
建表语句
CREATE TABLE [dbo].[Admin](
    [ID] [bigint] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](10) COLLATE Chinese_PRC_CI_AS NOT NULL,
    [PassWord] [varchar](100) COLLATE Chinese_PRC_CI_AS NOT NULL,
    [PurviewID] [int] NOT NULL,
    [Remember] [int] NULL,
    [AutoRun] [int] NULL,
    [DepartmentsID] [bigint] NULL,
 CONSTRAINT [PK_管理员_1] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
) ON [PRIMARY]
) ON [PRIMARY]
2、接着建立数据库模型
Model
 #region 内部成员字段
        private int _id;
        private string _Name;
        private string _Password;
        略...
#endregion
#region 方法
        public AdminInfo() { }


        public AdminInfo(string userName, string password)
        {
            this._Name = userName;
            this._Password = password;
        }
#endregion
3、建立DALFactory-----抽象工厂
public static IDAL.IAdmin Create()
        {
            string path=System.Configuration.ConfigurationSettings.AppSettings["DAL"];
            string className="SQLServerDAL.Admin";


            IDAL.IAdmin acount=(IDAL.IAdmin)Assembly.Load(path).CreateInstance(className);
            return acount;
        }
4、建立IDAL--------数据接口层
public interface IAdmin
    {
        AdminInfo Login(string userName, string password);
        int Insert(AdminInfo account);
        int Update(AdminInfo account);
    }
5、建立Utility----公共层
public static string ConnectionString()
        {
            return (ConfigurationSettings.AppSettings["ConnectionString"]);
        }
6、建立DBUtility----公共数据访问层和SQLServer数据访问层
DBUtility中建立SQLHelper类
SQLServerDAL的Admin类需要继承IAdmin
public class Admin:IAdmin
    {}
Admin类主要实现用户登陆功能
7、建立业务逻辑曾BLL
方法public static AdminInfo Login(string userName, string password){}
8、为PMIS主程序添加应用程序配置文件app.config
添加
   
   
 

在主程序的窗体中添加控件,为按钮添加事件
if (BLL.Admin.Login(参数) == null)
            {
               //处理...
            }
            else
            {
                //处理...
            }
========

C# 使用三层架构实例演示-winForm 窗体登录功能

http://blog.csdn.net/qq649792393/article/details/41450193


什么是三层架构?百度百科讲的很详细,大家可以去搜索。这篇文章并不是讨论这个问题。而是通过一个例子帮助大家理解三层。理论上的东西讲的比较少。希望可以帮助到像我这样的小白学习。希望可以帮助到大家!
个人觉得这个例子还是很基础的,但是也可以帮助大家理解三层的设计理念。完成了这个小例子之后,你可以轻松的创建拥有相同功能的asp页面,而不需要更改太多的代码,因为代码处理的逻辑与数据操作已经实现了,只需更改网页空间属性及调用方法即可,同时帮助了解分层的便利性。至于三层的缺陷,大家可以在以后的开发中慢慢了解。
好了废话不说了,下面我们就直接开始正文吧。


数据库设计相当简单,就一个数据库然后又张存着用户名和密码的表。
数据库设计:
数据库名称:threeLayer    
表: users     
列:1.username 账号   2.password  密码
数据库创建表的脚本如下:
[sql] view plain copy
CREATE TABLE [dbo].[users](  
    [id] [int] IDENTITY(1,1) NOT NULL,  
    [username] [varchar](50) NULL,  
    [password] [varchar](50) NULL,  
 CONSTRAINT [PK_users] PRIMARY KEY CLUSTERED   
(  
    [id] ASC  
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]  
) ON [PRIMARY]  
GO  
SET ANSI_PADDING OFF  
GO  
SET IDENTITY_INSERT [dbo].[users] ON  
INSERT [dbo].[users] ([id], [username], [password]) VALUES (1, N'admin', N'admin')  
INSERT [dbo].[users] ([id], [username], [password]) VALUES (2, N'user1', N'user1')  
INSERT [dbo].[users] ([id], [username], [password]) VALUES (3, N'user2', N'user2')  
INSERT [dbo].[users] ([id], [username], [password]) VALUES (4, N'user3', N'user3')  
SET IDENTITY_INSERT [dbo].[users] OFF  


三层数据传递整体思路:
用户输入账号密码->点击登录->进入BLL层进行输入与数据的逻辑处理->进入DAL层将BAL层的逻辑进行实现(用户输入的账号的密码与数据库匹配),返回结果
其中数据的传递用model实体类属性来传递
步骤:
新建一个windows 窗体应用程序项目并命名为threeLayerText,路径自己选吧,可以选择回收站


在自动新建的窗体项目中,双击Form1.cs,打开窗体设计。


在窗体中添加两个label,两个TextBox分别命名为textBoxAccount、textBoxtextBoxPsw和一个button 命名
为 butLogin。这里命名指的是控件name属性


为窗体添加一个应用配置文件:右键窗体项目文件-添加-新建项-应用程序配置文件


在配置文件节点中添加数据库连接语句
根据数据库配置Initial Catalog 为数据库名称,User ID 为登录数据库账户,Password 为改账号密码
添加后app.config完整内容如下
[html] view plain copy
 
 
   
              providerName="SQLClient" />  
 
 
 


添加类库:右键项目解决方案-添加-新建项目-类库,命名,确定
分别添加DAL、BAL、Model三个类库


在Model类库中添加userInfo类,用于在各个层之间传递数据
在类库中新建一个用户类 userInfo:右键Model类库-添加-类(或者选中model类库,使用shift+alt+c快捷键)
在userInfo类中添加属性
[csharp] view plain copy
private string _username;  
private string _psw;  
  
public string username  
{  
      set { _username = value; }  
      get { return _username; }  
}  
public string psw  
{  
      set { _psw = value; }  
      get { return _psw; }  
}  
Model类完整代码如下:
[csharp] view plain copy
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
  
namespace Model  
{  
    public class userInfo  
    {  
        private string _username;  
        private string _psw;  
  
        public string username  
        {  
            set { _username = value; }  
            get { return _username; }  
        }  
        public string psw  
        {  
            set { _psw = value; }  
            get { return _psw; }  
        }  
    }  
}  


在DAL层中添加数据连接、查询操作类和方法
添加system.configuration引用,使类可以读取配置文件节点,读取配置文件中连接数据库语句;右键引用-添加引用-选择程序集-勾选-确定




添加 DBbase类(右键DAL项目-添加-新建项-命名好-确定) 用于连接数据库,添加System.Data 和 System.Data.SqlClient 命名空间,别问我用来干吗,其实我也不知道用来干吗的。
创建一个基本的查询方法用于查询并返回记录条数。DBbase类完整代码如下:
[csharp] view plain copy
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Data;  
using System.Data.SqlClient;  
  
namespace DAL  
{  
    public class DBbase  
    {  
        //读取配置文件 连接数据库语句  
        public static string strCon = System.Configuration.ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString;  
        //public static string strCon = "Data Source=.;Initial Catalog=threeLayer;Persist Security Info=True;User ID=sa;Password=123";  
          
        //实例化连接对象 con  
        SqlConnection con = new SqlConnection(strCon);  
  
        //检测连接是否打开  
        public void chkConnection()  
        {  
            if (this.con.State == ConnectionState.Closed)  
            {  
                this.con.Open();  
            }  
        }  
  
        //执行语句,返回该语句查询的数据行的总数  
        public int returnRowCount(string strSQL)  
        {  
            chkConnection();  
            try  
            {  
                SqlDataAdapter da = new SqlDataAdapter(strSQL, con);  
                DataSet ds = new DataSet();  
                da.Fill(ds);  
                return ds.Tables[0].Rows.Count;  
            }  
            catch  
            {  
                return 0;  
            }  
        }  
    }  
}  
添加 userAccess类(右键DAL项目-添加-新建项-命名好-确定) 用执行查询语句查找用户输入账号密码在数据库中存在记录条数
userAccess类完整代码如下:
[csharp] view plain copy
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
  
namespace DAL  
{  
    public class userAccess  
    {  
        //实例化DBbase 对象  
        DBbase db = new DBbase();  
  
        //用户登录的方法  
        public int userLogin(string name, string psw)  
        {  
            string strsql = "select * from users where username = '" + name + "' and password = '" + psw + "'";  
            return db.returnRowCount(strsql);  
        }  
    }  
}  


在BLL层中添加用户输入数据与数据库匹配的逻辑代码
添加Model、DAL类库引用:右键BLL类库中引用文件夹,右键-添加引用-选择解决方案-项目-选中Model、DAL-确定
实例化DAL.userAccess 类,并新建一个方法调用DAL.userAccess方法,参数为Model实体类中的useInfo类,完整代码如下:
[csharp] view plain copy
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;   
  
namespace BLL  
{  
    public class userAccess  
    {  
        DAL.userAccess d_userAccess = new DAL.userAccess();  
        public int userLogin(Model.userInfo m_userInfo)  
        {  
            return d_userAccess.userLogin(m_userInfo.username, m_userInfo.psw);  
        }  
    }  
}  
回到窗体设计中,添加用户输入处理与调用BLL层方法
添加Model、DAL类库引用:右键threeLayerText项目中引用文件夹,右键-添加引用-选择解决方案-项目-选中Model、BLL-确定


打开窗体后台代码,实例化Model.userInfo 、BLL.userAccess。代码如下
[csharp] view plain copy
//实例化model层中 userInfo类用于传递数据  
Model.userInfo m_userInfo = new Model.userInfo();  
  
//实例化BLL层中 userAccess方法衔接用户输入与数据库匹配  
BLL.userAccess b_userAccess = new BLL.userAccess();  


双击登录按钮,添加点击事件。代码如下
[csharp] view plain copy
//将用户输入的账号密码 赋值给userInfo类 username、psw属性  
m_userInfo.username = textBoxAccount.Text.Trim().ToString();  
m_userInfo.psw = textBoxPsw.Text.Trim().ToString();  
  
//如果BLL层中 useLogin调用返回记录条数 大于1 则账号密码正确  
if (b_userAccess.userLogin(m_userInfo) > 0)  
{  
   MessageBox.Show("登录成功");  
}  
else  
{  
   MessageBox.Show("登录失败");  
 }  
完整Form1.cs 代码如下
[csharp] view plain copy
using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Linq;  
using System.Text;  
using System.Windows.Forms;  
  
namespace threeLayerText  
{  
    public partial class Form1 : Form  
    {  
        //实例化model层中 userInfo类用于传递数据  
        Model.userInfo m_userInfo = new Model.userInfo();  
  
        //实例化BLL层中 userAccess方法衔接用户输入与数据库匹配  
        BLL.userAccess b_userAccess = new BLL.userAccess();  
  
        public Form1()  
        {  
            InitializeComponent();  
        }  
  
        private void Form1_Load(object sender, EventArgs e)  
        {  
  
        }  
  
        //登录按钮 事件  
        private void butLogin_Click(object sender, EventArgs e)  
        {  
            //将用户输入的账号密码 赋值给userInfo类 username、psw属性  
            m_userInfo.username = textBoxAccount.Text.Trim().ToString();  
            m_userInfo.psw = textBoxPsw.Text.Trim().ToString();  
  
            //如果BLL层中 useLogin调用返回记录条数 大于1 则账号密码正确  
            if (b_userAccess.userLogin(m_userInfo) > 0)  
            {  
                MessageBox.Show("登录成功");  
            }  
            else  
            {  
                MessageBox.Show("登录失败");  
            }  
        }  
    }  
}  


保存,可以调试了。


关于Model实体层的描述:
Model又叫实体类,这个东西,大家可能觉得不好分层。我是这样理解的:UI<-->Model<-->BLL<-->Model<-->DAL,如此则认为Model在各层之间起到了一个数据传输的桥梁作用。不过在这里,我们不是把事情想简单,而是想复杂了。
摘自:http://www.cnblogs.com/sdjxcolin/archive/2008/12/12/1353780.html 这篇文章讲解了这个问题
========

C#中三层架构UI、BLL、DAL、Model实际操作

http://blog.csdn.net/zhgl7688/article/details/43669463


三层架构分为:表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)再加上实体类库(Model)


1、实体类库(Model),主要存放数据库中的表字段。


操作:


 (1)先建立实体类库Model,打开项目,在解决方案中右键--》添加--》新建项目--》选中类库--》改名Model--》确定


(2)选中Model类库--》Shift+ALT+C--》建立实体类。UserInfo类


[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
namespace Model  
{  
   public  class UserInfo  
    {  
        public string  UserName { get; set; }  
        public string  Password { get; set; }  
    }  
}  




2、数据访问层(DAL),主要是存放对数据类的访问,即对数据库的添加、删除、修改、更新等基本操作
操作:


(1)先建立数据访问层类库DAL,打开项目,在解决方案中右键--》添加--》新建项目--》选中类库--》改名DAL--》确定


(2)在DAL中添加对Model的引用,选中DAL--》Alt+P+R--》解决方案--》项目--》选中MOdel--》确定


(3)在DAL中添加对system.configuration的引用,选中DAL--》Alt+P+R--》程序集--》框架--》选中System.configuration--》确定


(4)建立数据访问类,选中DAL--》Shift+ALT+C--》建立数据访问类。UserDB类


[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
using System.Configuration;  
using Model;  
using System.Data;  
using System.Data.SqlClient;  
  
namespace DAL  
{  
    class UserDB  
    {  
        private string connString = ConfigurationManager.ConnectionStrings["connString"].ToString();  
        public int AddUser(UserInfo userInfo)  
        {  
            //对数据库进添加一个用户操作  
            string commandText = "insert into UserInfo (userName,Password)values(@userName,@Password)";  
            SqlParameter[] paras = new SqlParameter[]  
            {   
           new SqlParameter ("@userName",userInfo.UserName ),  
           new SqlParameter ("@Password",userInfo.Password )  
            };  
            return SqlHelper.ExecuteNonQuery(connString, CommandType.Text, commandText, paras);  
        }  
    }  
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
//添加其他对数据库操作  
}  
3、业务逻辑层(BLL)对传送数据进行逻辑判断分折,并进行传送正确的值。
(1)先建立业务逻辑层类库BLL,打开项目,在解决方案中右键--》添加--》新建项目--》选中类库--》改名BLL--》确定


(2)在BLL中添加对Model、DAL的引用,选中BLL--》Alt+P+R--》解决方案--》项目--》选中MOdel、DAL--》确定


(3)建立业务逻辑类,选中BLL--》Shift+ALT+C--》建立业务逻辑类。LoginManager类
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
using DAL;  
using Model;  
  
namespace BLL  
{  
    public class LoginManager  
    {  
        private UserDB userDB = new UserDB();  
        public bool Add(UserInfo userInfo, out string messageStr)  
        {  
            messageStr = "";//返回界面层添加用户返回信息  
            bool isSuccess = false;  
            if (userInfo.UserName.Trim().Length != 0)//判断从传递来的username是否为空  
            {  
                if (userDB.IsEquals(userInfo))//传给DALl操作判断数据库中是否有重复值  
                {  
                    userDB.AddUser(userInfo);//传给DAL操作增加一个新用户  
                    isSuccess = true;  
                }  
                else  
                    messageStr = "有相同的值";  
            }  
            else  
            {  
                messageStr = "不能为空";  
  
            }  
            return isSuccess;//返回界面层是否添加成功  
        }  
    }  
}  


5、表现层(UI)即用户界面层
(1)在UI中添加对Model、BLL的引用,选中UI--》Alt+P+R--》解决方案--》项目--》选中MOdel、BLL--》确定


(2)编写代码传递数据给BLL层。


[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
    UserInfo userInfo;  
    LoginManager lm = new LoginManager();  
    private void btnAdd_Click(object sender, EventArgs e)  
    {  
        userInfo = new UserInfo()  
        {  
            UserName = txtUserName.Text.Trim(),  
            Password = txtPassword.Text.Trim()  
        };  
        string messageStr = "";  
  
        if (lm.Add(userInfo, out  messageStr))  
        {  
            MessageBox.Show("添加成功");  
        }  
        else  
        {  
            MessageBox.Show(messageStr);  
            txtUserName.Focus();  
        }  
  
    }  
}  
========

用三层架构来做winform程序

http://blog.csdn.net/clb929/article/details/54295211


  三层架构是一种代码分层思想,简单的说就是将一个项目分为界面展示、业务逻辑、数据访问三层,各层之间保持一定的独立性,降低代码之间的耦合性,这样做的好处是显而易见的:
1、各层之间的改动不会影响到其他层(比较大的变动除外,如果客户要求业务流程、数据库结构都变了,你还期望有什么不会变呢)


2、基本不用写SQL语句了,自动生成的代码是参数化查询,可以防止SQL注入


3、代码条理清楚,便于理解
  当然三层架构不是拯救一切的灵丹妙药,比如:
1、比较小的项目何必纠结用什么架构呢,在你琢磨架构的时候,用winform可能已经写完了
2、速度会有所降低,相对于直接访问数据库,三层架构增加了中间层,速度降低是肯定的


  说到三层架构,可能第一时间想到的就是mvc,然而三层架构并不是web的专利,归根结底,三层架构只是一种代码分层思想,winform当然也可以用,只不过界面展示这块,mvc是网页的形式,winform是windows窗体,其他两层思路是一样的。
  下面就以一个非常简单常见的商铺展示程序来实际讲解winform中如何实现三层架构。
一、前期准备
1、动软代码生成器,国产神器,你值得拥有,全自动生成数据访问层代码,百度就能找到,最后一版是2.78,作者没有继续更新了。已经免费开源,喜欢研究源代码的可以继续扩展。


李天平的博客


http://blog.csdn.net/litp
http://www.cnblogs.com/ltp/category/44293.html
2、SQLiteStudio,选择SQLite数据库是因为轻巧、无需安装,对于这个示例程序足够用了  ,SQLiteStudio是免费好用的SQLite数据库图形化管理工具,百度可得绿色版。
二、开发过程
1、下载动软代码生成器,安装完成之后运行,连接到附件示例程序的SQLite数据库,打开连接,右键点击数据库,选择“新建.net项目”,选择“简单三层结构”,下一步,选择“Shops”、“Users”两个表,点击“开始生成”。


2、来到生成目录,打开源代码,可以看到5个项目,下面分别说说他们的作用


BLL--业务逻辑层,所有的业务逻辑全部写在这里,动软已经为每个表自动生成了一个业务类,类名就是表名,BasicMethod区段是自动生成的一些基础方法,比如增删改查、分页查询这些,ExtensionMethod区段是空的,我们自己写的业务代码写在这个区段。


DAL--数据访问层,所有的数据库访问的基础方法写在这里,动软已经为每个表自动生成了一个数据访问类,类名就是表名,BasicMethod区段是自动生成的一些基础方法,比如增删改查、分页查询这些,ExtensionMethod区段是空的,如果我们觉得这些基础的数据库操作方法不够用,可以在这个区段添加自己的数据库操作方法,但是只有数据库的操作方法应该写在DAL类库。
DBUtility--数据库访问的基础类库,封装了MySQL,Sql,OLE,SqlLite,Oracle等数据库访问的方法,与ADO.NET相关的connection,DataAdapter,Command等全部在这里,DAL是在DBUtility基础上的进一步封装的,这个类库基本不需要修改。
Model--数据库表结构的映射,每一个类名代表数据库中的一个相同名字的表,类的每一个字段、属性表示表中对应的字段,数据库的一条记录就对应类的一个对象,这个类库基本不需要修改。


Web-- 一些基础的网页,因为我们是做winform的,所以这个不需要了,但是先别急着删,等下我们还要来拷连接字符串。
最后在解决方案文件夹下有一个Lib文件夹,是一些动态链接库,看看上述每个项目缺什么就引用什么。


3、新建一个winform项目,在项目的属性里将目标框架设置为".net framework 4"(不是".net framework 4 profile"),这样就有一个app.config文件了,打开app.config,打开Web项目根目录下的Web.config文件,将appSettings整个一节拷贝到app.config文件configuration节点内,将连接字符串修改为SqlLite的格式,删除Web项目。


  补充一点,我们的程序是怎么得到连接字符串的呢?在DBUtility类库里,有一个PubConstant类,里面有一个ConnectionString属性,通过ConfigurationManager.AppSettings["ConnectionString"]读取了app.config文件里保存的连接字符串。


  接下来就是开始做界面,写代码了,winform相信大家都很熟悉了,具体过程我就不多说了,直接上源代码。


  示例程序源代码:


http://pan.baidu.com/s/1jIRZkfO
总结:


1、动软自带的SQLite动态链接库比较老,用他原来的运行不起来,我换成了新版的,在Lib文件夹下的SQLite.Interop.dll和System.Data.SQLite.DLL,System.Data.SQLite.DLL需要在项目中引用,SQLite.Interop.dll要手动拷贝到生成目录


2、如果代码写完后数据库结构发生了变化(比如增加了一个字段),我能想到的办法就是重新用动软生成一次,将BLL,DAL,DBUtility,Model替换掉,所以最好这几个项目中不要写自己的代码了,要扩展的话重新建项目吧。为什么不推荐手动改呢,因为即便是增加一个字段,也可能涉及到几个类的修改,改动大就更不用说了,手动改代码的话很有可能漏掉,能用最简单的办法搞定的事就用最简单的办法。
========

你可能感兴趣的:(.Net)