我在项目中碰到这么一个问题:
有两个类,a和b,分在两个类库中,实现同一个接口c,ab的对象是在a类的单例模式中根据if else 创建,用接口c作为返回类型。因为在a中可能会创建b的对象,自然a需要引用b 的库,因为c接口写在了b所在库中,因此也相当于同时引用了c的库。
b的对象只有在a类的单例模式中符合if条件才会创建,假设a、b所在库都特别臃肿,那么是否有必要将c接口提取到一个单独的类库中再引用呢?
另外我还了解到dll可以用反射的方式动态加载。
不知道这三种方案哪种性能最优,请博友指教。
没理解错的话你是a依赖c,b,b依赖c
底线是不允许循环引用,因此c单独提到一个项目中供a,b引用最好
反射可以解决循环引用,但这里不建议这样做,这样做了后会让真实的依赖关系变复杂,不方便排查问题。
性能上其实都一致(你a是单例,所以反射也就一次就完了)
是这样的依赖关系。
我测试了下,dll是在被引用时即加载,而不是在其中函数被调用时才加载,而项目在调用时才会读它的依赖项(引用),也就是说:
假设a依赖c,b,b依赖c,主项目m依赖a,同时因为a对象返回的类型是c,m也依赖c,则在m启动时即会加载a和c(所在库),而当程序执行到调用a 的函数时,因为a依赖b,则加载b,然后再执行该a函数里面的代码。
不清楚这是不是所谓的隐式加载,不知显示加载又是如何实现的。
按照这种加载顺序,将c提取到一个单独的库中应该有更高的性能,因为如果c写在b所在库的话,m启动时即会加载b,b比c臃肿,自然加载的比较慢,而且好像还不能被释放。
不知我的理解是否正确。
@怀川: 加载这块慢点又如何?你整个程序也就一次加载而已,而且程序集被加载是不能被释放的。
@Daniel Cai: 项目组长要求我把接口提取出来,但他又讲不清为什么。
令人费解。
@怀川: 接口提出来只是一个笼统的说法,我估计本意是要把这块给理下,把外部可访问的接口提出来
@Daniel Cai: 他原先的想法是用什么工厂模式把sqlserver的数据访问层逐渐切换到mysql,或作为一个备选项。
我对工厂模式不熟,就单独做一个mysql 的数据访问层,按接口抽象的方式给他缕,这样改动最小。
@怀川: 如果你们代码写死了ms的sqlprovider这个没办法,但如果是配置出来的话只需要改配置就完了。(当然代码中只能使用ado.net提供的接口方法,比如IDataReader而不是针对mssql的datareader)