应用反射+配置文件+抽象工厂时出现的错误和原因分析

    先来看一段程序:

<pre name="code" class="vb">Imports System.Configuration    '配置文件命名空间
Imports System.Reflection       '反射命名空间
Imports IDAL                    '引用接口层

Public Class DataAccess
    '程序集名称(同时代表命名空间名称):DAL
    Private Shared ReadOnly AssemblyName As String = System.Configuration.ConfigurationManager.AppSettings("assname")
    '数据库类型:Sql
    Private Shared ReadOnly db As String = System.Configuration.ConfigurationManager.AppSettings("DB")
    '创建D层类SqlUserInfoDAL的实例
    Public Shared Function CreateUserInfo() As IDAL.IUserInfo
        Dim dalUserInfoName As String = AssemblyName & "." & db & "UserInfoDAL"        '要实例化的D层类的名称
        Return CType(Assembly.Load(AssemblyName).CreateInstance(dalUserInfoName), IUserInfo)
    End Function

 

    对于学过反射+配置文件+抽象工厂实现数据访问的人来说,这段程序还是很容易理解的。我将这段程序用在了机房收费系统个人重构版中。如图所示:

    但是在运行过程中却报了错:

    未能加载文件或程序集“DAL”或它的某一个依赖项。系统找不到指定文件。

    通过查资料,知道了一种解决方案:将DAL层的DAL.dll文件复制到UI层相应的目录下,如图所示。

    之后,程序正常运行,并通过CreateUserInfo()创建出了SqlUserInfoDAL的实例。

    有了成功的经验,我便做了如下操作:

  • 在DAL层,添加了一个新的类:SqlWorkLogDAL
  • 在DataAccess中,添加了一个新的方法:CreateWorkLog()

    如下所示:

 '创建D层类SqlWorkLogDAL的实例
    Public Shared Function CreateWorkLog() As IDAL.IWorkLog
        Dim dalWorkLogName As String = AssemblyName & "." & db & "WorkLogDAL"          '要实例化的D层类的名称
        Return CType(Assembly.Load(AssemblyName).CreateInstance(dalWorkLogName), IWorkLog)
    End Function

    但是运行后,还是报了错,不过这次错误不一样:

    未将对象引用设置到对象的实例。

    通过查资料,也找到了答案:修改DAL层--属性--编译--生成输出路径,将生成输出路径改到UI层\bin\Debug文件夹下。

    虽然两种解决方法不一样,但是本质都是把DAL层的DAL.dll文件放到UI层

    那么,为什么第一种解决方法只有“短暂疗效”,而第二种方法可以“根治”呢?

    这时,我做了个尝试,我不去修改路径,而是再次把DAL层中的DAL.dll文件复制并替换我刚才复制到UI层的文件。

    结果成功了。

    这就说明了:两次复制的文件并非同一个文件,虽然它们都叫DAL.dll,但是在文件内部,它们一定发生了变化。

这里我们就要说说,dll文件是怎么生成的了。

    每个程序集下面都有两个文件夹bin和obj,如图:


    bin目录用来保存项目生成后程序集,obj目录用来保存编译结果。编译是分模块进行的,编译整个完成后会合并为一个.dll或.exe文件保存到bin目录下。而且采用增量编译的方式。

    所以,当我添加了一个新的类SqlWorkLogDAl后,生成的DAL.dll已经不是原来的DAL.dll了。

    复制的方式的缺陷在于:只要DAL层发生变化,就得通过手动复制来更新U层的DAL.dll文件。但是修改路径,就不用我们管了,它会自动将最新的DAL.dll文件生成到UI层。

    那么为什么要把D层的.dll文件在U层生成呢?

     这就要知道Assembly.Load()是怎么定位程序集了?

     当你只给定程序集名称时,如“DAL”,那么CLR只会在应用程序的目录下查找,而咱们的应用程序在UI层,所以要在U层有DAL.dll。

    问题又来了:

    在U层,有Entity.dll,有BLL.dll,有DataAccess.dll……为什么就是没有DAL.dll,为什么只有它需要修改生成路径?

     这里就要看看程序的包图了:


    ---->代表依赖,也表示引用,那么从UI层看,UI层可以直接或间接地引用Facade层,BLL层,DataAccess层,IDAL层,但是没有引用DAL层,所以别的层的.dll文件会出现在U层,而DAL层的.dll文件没有出现在U层。

    文章中,如果有理解得不对的地方,还请大家批评指正。

评论 51
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值