由于公司产品需要用到反射技术。将平台和业务进行分离。由于某一部分的业务,实现的动态库(dll)并没有配置文件。因此,平台在启动以后就需要加载这些没有配置文件的动态库。
加载每个动态库,获取程序集中所有的Type。判断那些Type实现了某个接口,如果实现了,将此程序集记录下来。
以下是一个DEMO代码:平台程序集:Platform
平台提供给业务层接口程序集:FrameInterface
业务逻辑程序:BusinessLay
每个业务按照平台提供的接口进行实现。并且将程序集放在平台规定的路径下,每当平台启动以后,就会读取该路径,动态加载。
平台加载核心代码:
<span style="white-space:pre"> </span> string[] dllFiles = Directory.GetFiles(path, "*.dll"); <span style="white-space:pre"> </span> Assembly assembly = null; Type typeISynchronizeData = typeof(ISynchronizeData); foreach (string dllFileName in dllFiles) { Console.WriteLine(dllFileName); assembly = Assembly.LoadFrom(dllFileName); Type[] types = assembly.GetTypes(); foreach (Type t in types) { // 判断该类是否实现ISynchronizeData接口 <span style="background-color: rgb(255, 102, 102);"> bool result = typeISynchronizeData.IsAssignableFrom(t);</span> Console.WriteLine(result + ":"); if (result) { // 创建实例 ISynchronizeData syn = Activator.CreateInstance(t) as ISynchronizeData; if (syn != null) { SynchronizeDataBean sysBean = syn.GetDescribe(); if (!mAssemblyCollection.ContainsKey(sysBean.Code)) { SynchronizeBusinessAsmBean sba = new SynchronizeBusinessAsmBean(); sba.Syn = sysBean; sba.SynData = syn; mAssemblyCollection.Add(sysBean.Code, sba); mSynDataTypes.Add(sysBean); } } } } }
就是这一段代码调试花了两个小时。做了各种尝试。画红线部分返回永远都是false。
原因就是:
string[] dllFiles = Directory.GetFiles(path, "*.dll");
这句代码返回的数组中,将平台封装的接口的程序集也放进这个数组,而且在真正实现这个接口的程序集之前。最后我将数组写死,将真正实现平台接口的程序集放在前面,接口程序集放在
后边,测试是正常。
结论:只要是接口程序集在返回的数组之前,红色部分返回永远都是false。
解决办法:由于我们需要将真正实现接口的程序放在数组的前面,但是这不好控制,所以,最好的解决方法就是将平台接口程序集不要放置到规定的路径下即可。