项目要求使用SqlServer数据库与Access数据库切换。需求是仅仅要把webconfig中的配置一改就能够实现数据来源在SqlServer与Access之间切换。经过思考,认为能够用抽象工厂来实现这一功能,后边细致一想,感觉有点麻烦,后边想到了用反射来实现。
思路是这种:将数据訪问层抽取出来,提取成接口DomeIDAL类库,再不同的数据库建立不同的数据訪问层实现接口,如使用SqlServer话就相应有一个SqlServer的数据訪问类库项目SqlServerDAL,里面的类相应实现DemoIDAL中的接口,Access有AccessDAL数据訪问类库相应,这样将不同的数据库的訪问抽取出来。然后再建一个反射工厂DemoFactory,用来创建不同的数据訪问对象,实现是这种,在webconfig中配置要使用的数据訪问层的程序集名称,如使用Access的话,就配AccessDAL,然后在发射工厂中读webconfig配置,这样就能利用发射载入该程序集了,然后在BLL层中传相应的类名,让工厂来生产出该类的对象。这样就实现了仅仅要在webconfig中配置好要使用的数据訪问层的程序集名称,就能实现使用那个数据訪问层来訪问数据库了。
比如在数据訪问层有这种两个接口IUser和IProduct 分别用SqlServer和Access实现的方式例如以下图所看到的:
如今通过业务逻辑层BLL 须要实例化一个实现了IUser的实例来訪问DAL层
假设直接使用IUser userRep=new SqlServerUser() 则BLL层和DAL层之间有着强耦合的关系。 不够完美
当须要更改DAL层为Access方式实现时,须要修改大量的BLL层new的实例代码。
能够使用 抽象工厂加反射的方式,通过反射机制获取配置文件里的信息,来确定是使用哪种方式实现的DAL层。
通过抽象工厂 是的BLL层和DAL的訪问依赖于工厂,达到解耦的目的
PS:配置文件必须在界面层
反射的写法:
objType=Assembly.Load(AssemblyPath).CreateInstance(className);
当中:AssemblyPath指程序集名。className 指命名空间.类名称。
反射的一个原则:
一切皆以UI层的bin目录中的dll名称为中心。(原因非常easy:.net类载入的机制就是默认从本程序集的bin文件里找,所以bin目录中一定要有要载入的程序集的dll)。UI层中bin目录中dll叫什么名字AssemblyPath就使用什么名字,bin内部类的全名叫什么,className就写成什么全名。.net中的引用:增加对某个程序集的引用就能在程序集有变化时自己主动拷贝dll。