C#は7層のログインウィンドウを使用します

7階とは?

私が理解している7つのレイヤー:3つのレイヤーに基づいて、外観レイヤー、ファクトリレイヤー、インターフェイスレイヤーを7つのレイヤーに追加します。そうすることで、コードをより適切に分離できます。

以下は私が描いた7層の絵です
。7層の関係を理解するのに役立ちます。
ここに画像の説明を挿入

Uレイヤー:アピアランスレイヤーを参照し、アピアランスレイヤーをインスタンス化し、Bレイヤーから返された情報を受け取ります。
エンティティ層を参照し、エンティティ層をインスタンス化して情報を受け取ります。
構成ファイルは、U層のApp.configファイルにも書き込む必要があります。
Winformフォームコントロールのイベント

ファサード:物理層への参照。
レイヤーBへの参照、レイヤーBオブジェクトのインスタンス化

Bレイヤー:エンティティレイヤーを参照し、Dレイヤーから返された値を受け取り、
IDALインターフェイスレイヤーを参照し、ファクトリメソッドを呼び出してインターフェイスを作成
し、ファクトリファクトリレイヤーを参照して、ファクトリをインスタンス化します。

IDALインターフェースレイヤー:データテーブルを見つけるために、エンティティレイヤーを参照してください

ファクトリファクトリレイヤー:Dレイヤーを参照するには、Dレイヤーのクラス名を使用する必要があり
ます。IDALインターフェイスレイヤーが参照され、リフレクションが適用されます。
構成ファイルを参照してください。構成ファイルを参照するときは、アセンブリを参照して構成ファイルを受け取る必要があります。
ここに画像の説明を挿入

Dレイヤー:参照インターフェイスレイヤー:インターフェイス
参照エンティティレイヤーを実装するメソッド:データベースデータを
返すSqlHelperもDレイヤーにあり、クエリを実行してクエリテーブルに戻ります。

7層コード

エンティティレイヤー

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Entity
{
    
    
    public class UserInfo
    {
    
    
        
        public int UserId {
    
     get; set; }
        public string UserName {
    
     get; set; }
        public string PassWord {
    
     get; set; }
        
    }
}

U层

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace LoginUI
{
    
    
    public partial class Form1 : Form
    {
    
    
        public Form1()
        {
    
    
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
    
    
            Entity.UserInfo entity = new Entity.UserInfo();
            //实例化实体层,用来接收信息
            entity.UserName = txtUserName.Text.Trim();
            entity.PassWord = txtPassword.Text;
            LoginFacade.Facade facade = new LoginFacade.Facade();
            //实例化外观层,接受B层返回来的信息

            bool flag = new bool();
            flag = facade.SelectUser(entity);
            {
    
    
                if (flag != false)
                {
    
    
                    if (true)
                    {
    
    
                        this.Hide();
                        MessageBox.Show("登录成功!");
                    }
                }
                else
                {
    
    
                    MessageBox.Show("用户名或密码输入错误,请重新输入!");
                    txtPassword.Clear();
                    txtUserName.Clear();//清空
                    txtUserName.Focus();//光标定位
                }
              }
            }
       
       }
}

構成ファイル

<appSettings >
		<add key="ConnStr" value ="Server=LAPTOP-4EF4CAKC;Database=Login;User ID=sa;Password=123"/>
		<!--   Server=Login,Database=Users     -->
		<add key="DB" value ="DAL"/>
	</appSettings>

ファサード層

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LoginFacade
{
    
    
    public class Facade
    {
    
    
        public Boolean SelectUser (Entity .UserInfo enuser)
            
        {
    
    
            bool flag;
            LoginBLL.BLL bll = new LoginBLL.BLL();//实例化B层对象
            flag = bll.UserBLL(enuser);
            return flag;
            
            
        }
    }
}

B層

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;//新添加
using System.Xml;
using LoginFactory;
using IDAL;

namespace LoginBLL
{
    
    
   public  class BLL
    {
    
    
        public bool UserBLL(Entity.UserInfo userInfo)
        {
    
    
            LoginFactory.Factory factory = new LoginFactory.Factory();
            //实例化一个工厂
            IDAL.LoginIDAL idal = factory.CreatUser();
            //调用工厂方法创建接口
            DataTable table = idal.GetUsername(userInfo);
            //接受D层返回的值

            bool flag = new bool();
            if (table.Rows.Count == 0)
                //返回的是data的类型。如果行数为0,说明没有该账号
            {
    
    
                flag = false;
            }
            else
            {
    
    
                flag = true;
            }
            return flag;
        }
    }
}

IDAL层

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;//新添加的,表示对ADO.NET结构类的访问,可以生成多个管理数据源的数据组件

namespace IDAL
{
    
    
    public interface  LoginIDAL //接口名
    {
    
    
        DataTable GetUsername(Entity.UserInfo userInfo);
        //内存数据中的一个表,为了实现“查”?用户名?
    }
}

ファクトリーレイヤー

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;//反射
using System.Configuration;//配置文件
using System.Security.Cryptography.X509Certificates;
using System.Data.SqlTypes;

namespace LoginFactory
{
    
    
    public class Factory
    {
    
    
        string strDB = ConfigurationManager.AppSettings ["DB"];
        //接受配置文件
        public IDAL .LoginIDAL CreatUser()
        {
    
    
            string ClassName = strDB + "." + "LoginDAL";//D层的类名
            return (IDAL.LoginIDAL)Assembly.Load(strDB).CreateInstance(ClassName);
            //反射的应用
        }
    }
}

DAL層

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;//数据库?
using System.Data;//表示对ADO.NET结构类的访问
using System.Configuration;//配置文件
using System.Data.SqlTypes;
using Entity;

namespace DAL
{
    
    
    public class LoginDAL:IDAL.LoginIDAL//实现接口的方法 命名空间.类名
    {
    
    
        public DataTable GetUsername(Entity .UserInfo userInfo)
            //继承接口层就要与接口层一致
        {
    
    
            SqlHelper sqlhelper = new SqlHelper();
            SqlParameter[] sqlParams = {
    
    new SqlParameter ("@UserName",userInfo.UserName),
            new SqlParameter(@"PassWord",userInfo.PassWord)};
            string sql = @"SELECT * FROM Users WHERE UserName = @UserName AND Password = @Password ";
            DataTable table = sqlhelper.ExecuteQuery(sql, sqlParams, CommandType.Text);
            return table;//返回的是一个table类型
        }
    }
}

SqlHelper

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;//数据库?
using System.Data;//表示对ADO.NET结构类的访问
using System.Configuration;//配置文件
namespace DAL
{
    
    
    public class SqlHelper
    {
    
    
        private SqlConnection conn = null;
        private SqlCommand cmd = null;
        private SqlDataReader sdr = null;//只读

        public SqlHelper()
        {
    
    
            string connStr = ConfigurationManager.AppSettings["connStr"];
            //Configuration提供对客户端应用程序配置文件的访问
            conn = new SqlConnection(connStr);
        }
        private SqlConnection GetConn()
        {
    
    
            if(conn.State == ConnectionState.Closed)
            {
    
    
                conn.Open();
            }
            return conn;
        }
        public DataTable ExecuteQuery(string cmdText, SqlParameter [] paras, CommandType ct)
        {
    
    
            DataTable dt = new DataTable();
            cmd = new SqlCommand(cmdText, GetConn());
            //CmdText查询的文本,getConn是上边的一个sqlconnection表示到sql 的连接
            cmd.CommandType = ct;
            //如何解释CommandText属性,CommandText指的具体的什么指令
            cmd.Parameters.AddRange(paras);
            using (sdr = cmd.ExecuteReader(CommandBehavior .CloseConnection ))
            //ExecuteReader CommandBehavior将Commandtext发送到Connection
            //并且使用CommandBeHavivor值之一生成SQLDataReader
            {
    
    
                dt.Load(sdr);
                //填充DataTable使用所提供的数据源中的值DataReader
            }
            return dt;
            //返回的是一个表
        }

        
    }
}

7階で発生した問題:

1.System.NullReferenceException:オブジェクト参照がオブジェクトのインスタンスに設定されていません

解決策1

2.抽象ファクトリ+リフレクション(ファイルまたはアセンブリ「DAL」またはその依存関係の1つをロードできませんでした。システムは指定されたファイルを見つけることができません)

解決策2

おすすめ

転載: blog.csdn.net/weixin_44690047/article/details/109577220