天天看點

反射加載

由于公司産品需要用到反射技術。将平台和業務進行分離。由于某一部分的業務,實作的動态庫(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。

解決辦法:由于我們需要将真正實作接口的程式放在數組的前面,但是這不好控制,是以,最好的解決方法就是将平台接口程式集不要放置到規定的路徑下即可。