七层连连串

    在个人重构之前,在三层学习之后,加入七层的跨越连接,整体感觉还是不错的。

【1】先看下包图:其实在七层敲完后才感觉一目了然,,,

七层连连串_第1张图片

   当时感觉包图好宏观,却不清楚内部层与层之间的关系。所以我用下面一张图,来说明我对七层的理解。

当然这里我加入了SqlHelper类,所以,称之为七层,八层也是可以理解的。

七层连连串_第2张图片

    用这样一段话来描述这幅图:

    U层:接受用户传来的数据,传给外观,再由外观传递给B层判断用户的实际性。而在B层逻辑判断的过程中,要用到抽象工厂加反射技术来判断具体应该实例化的DAL类,以及用到抽象工厂返回的接口,换句话说,这个接口类就是对D层的一个封装,具体的接口实现还是由D层实现,然后返回给B层进行逻辑判断。而sqlhelper的加入,是将D层对数据库的增删改查的过程进行了封装,这样直接由D层传递参数进去,返回的就是相应的查询结果。

下面以具体代码来详细了解。(这里从B层开始,因为U曾和外观都很容易理解)

B层:

<span style="font-family:SimSun;font-size:18px;">Public Class loginBLL
    '检查用户名是否存在

    Public Function IsExists(ByVal user As Entity.LoginUserInfo) As DataTable
        Dim factory As New Factory.LoginFactory()
        Dim Iuser As IDAL.IuserinfoDAL
        '实例化接口为:已经通过抽象工厂+反射选择数据库后的DAL层。
        Iuser = factory.CreateUserInfo()
        Dim table As DataTable
        table = Iuser.selectUser(user) '通过该DAL层返回table,也就是说这个接口方法的实现是通过该DAL层实现的。
        Return table

    End Function</span>

配置文件:

<span style="font-family:SimSun;font-size:18px;"><?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
      <add key="ConnStr" value ="Server=jialimin;Initial Catalog=Login;User ID=sa;Pwd=1"></add>
      <add key ="DB" value="DAL"/>
    </appSettings>
</configuration></span>
抽象工厂+反射:

<span style="font-family:SimSun;font-size:18px;">Imports System.Configuration '添加对配置文件的引用
Imports System.Reflection '添加对反射的引用
Imports IDAL
'抽象工厂负责数据库的选择和创建接口
'我理解的抽象工厂加反射目的:通过字符串赋值来选择不同数据库的DAL层。
Public Class LoginFactory
    '选择数据库,通过读配置文件给DB字符串赋值。
    Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DB")


    Public Function CreateUserInfo() As IuserinfoDAL
        ' 反射的写法:
        'objType=Assembly.Load(AssemblyPath).CreateInstance(className)
        '其中:AssemblyPath指程序集名。className指命名空间.类名称。
        Dim Iuser As IuserinfoDAL
        Iuser = CType(Assembly.Load("loginDAL").CreateInstance("loginDAL" & "." & "LoginUserDAL"), IuserinfoDAL)
        Return Iuser
    End Function</span>
接口层:

<span style="font-family:SimSun;font-size:18px;">Imports Entity
Public Interface IuserinfoDAL
    Function selectUser(ByVal user As Entity.LoginUserInfo)
    Function UpdateScore(ByVal Score As Entity.LoginScoreInfo)

End Interface</span>

D层:

<span style="font-family:SimSun;font-size:18px;">'system.data.sqlclient命名空间是sqlserver的.net framework 数据提供程序。
Imports System.Data.SqlClient
Imports Entity
Imports IDAL
Imports SQLHelper


Public Class LoginUserDAL : Implements IDAL.IuserinfoDAL
    '定义一个sqlhelper对象。
    Private SqlHelper As SQLHelper.sqlHelper = New SQLHelper.sqlHelper()

    '实现接口的selectuser方法。
    Public Function selectUser(user As LoginUserInfo) As Object Implements IuserinfoDAL.selectUser
        Dim sql As String
        Dim table As DataTable
        Dim sqlParams() As SqlParameter = {New SqlParameter("@username", user.UserName), New SqlParameter("@password", user.Password)}
        sql = "select * from [User] where UserName=@UserName and Password =@password"
        table = SqlHelper.GetDataTable(sql, CommandType.Text, sqlParams)
        Return table
    End Function
</span>

SqlHelper层:

<span style="font-family:SimSun;font-size:18px;">Imports System.Data.SqlClient
Imports System.Configuration
Imports System.Data

'''其sqlHelper类中的属性和方法不可继承或实例化
Public Class sqlHelper
    '获取当前应用程序默认配置文件中的 AppSettingsSection 数据,ConnStr该字符串就是配置文件中设置连接数据库的那部分。
    Public Shared connectionString As String = ConfigurationManager.AppSettings("ConnStr")

    ''' <summary>
    '''执行带参数的查询方式,返回值为表。
    ''' <param name="cmdTxt" >参数cmdText为所要执行的sql语句</param >
    ''' <param name=" cmdType">查询时的查询方式</param> 
    ''' <param name="paras" >查询时的命令参数</param>
    ''' <returns >查询后以表的形式返回,</returns >
    ''' </summary>
    ''' <remarks></remarks>

    Public Shared Function GetDataTable(ByVal cmdTxt As String, ByVal cmdType As CommandType, ByVal paras As SqlParameter()) As DataTable

        Dim conn As SqlConnection = New SqlConnection(connectionString) '创建数据库的连接
        Dim cmd As SqlCommand  '定义命名变量
        Dim adataset As DataSet '定义数据适配器,DataSet类表示一个存放于内存中的数据缓存
        Dim adaptor As SqlDataAdapter 'SqlDataAdapter类目的是填充DataSet
        cmd = New SqlCommand(cmdTxt, conn) '在conn上面执行实例化命令变量,并执行语句cmdtype
        cmd.CommandType = cmdType '命令执行的类型
        cmd.Parameters.AddRange(paras) '命令执行的参数
        adaptor = New SqlDataAdapter(cmd) '初始化 SqlDataAdapter 类的新实例,用指定的 cmd 作为 SelectCommand 的属性
        adataset = New DataSet
        Try
            If conn.State = ConnectionState.Closed Then
                conn.Open()
            End If
            adaptor.Fill(adataset) '向adaptor对象中填充查询的数据
        Catch ex As Exception
            MsgBox(ex.Message, , "数据库操作")
        Finally
            If conn.State = ConnectionState.Open Then
                conn.Close()
            End If
        End Try
        Return adataset.Tables(0) '获取包含在 DataSet 中的表的集合。

    End Function</span>
【2】我认为的难点:

1·配置文件的两个参数:“ConnStr”和“DB”

conntr: 该字符串的值就是设置连接数据库的。最后作为参数传递给SqlHelper类的connectionString 字符串。(如图所示)


DB: 该字符串的值用于数据库的选择。最后作为参数传递给抽象工厂类的strDB字符串。(如果所示)


 反射的用法:
   objType = Assembly.Load(AssemblyPath).CreateInstance(className)
   其中:AssemblyPath指程序集名。className指命名空间.类名称。
   起初,虽然知道这两个参数,但我实在不明白程序集是哪个?然后那个className又是什么?后来看到社河师哥才有了那么点感觉。
     反射的一个原则:
一切皆以UI层的bin文件夹中的dll名称为中心。
     原因很简单:
在我们每次重新生成解决方案,程序运行时,程序集的bin文件中会生成所有要加载的程序集的dll文件,(实在不明白,可以在UI层的bin文件中找到dll文件。)而 .net类加载的机制就是默认从本程序集的bin文件中找,所以bin文件夹中一定要有要加载的程序集的dll。所以,UI 层中bin文件夹中dll叫什么名字AssemblyPath就使用什么名字,而className就是默认的D层的命名空间和类名。如果所示:(框出的两部分一样)
七层连连串_第3张图片

【3】遇到的问题:
1· DALFactory出现"未能加载文件或程序集“DAL”或它的某一个依赖项。系统找不到指定的文件”的解决方案 .
七层连连串_第4张图片
   
    这个问题就设计到上面说到的“加载dll文件”一事,我的问题是: dll文件存在,但是加载路径不对。在我的UI层的bin文件夹下没有D层生成的dll文件,那么程序运行时必然会报错,因为它在UI层根本找不到生成的dll文件, 解决方案有两种:1·手动添加(想想都知道,这肯定不是好办法)2·右击D层名称,选择属性,如图所示:改变其生成输出路径为UI层下的bin文件夹的Debug中。
七层连连串_第5张图片

     差不多总结出来就是这些,我把我当时认为比较混的一些东西:包括七层的联系,抽象工厂+反射,以及很棘手的一些常见错误,都总结一番,如若有不对之处,还望大神们斧正!







你可能感兴趣的:(SQLHelper,七层,抽象工厂+反射,加载DAL失败)