一,普通的一段代碼html
以前寫了兩個軟件, 一個是阿里雲客戶端,一個是淘寶刷單軟件,都用到了IOC技術。安全
個人作法是在引導程序中,把程序須要用到的DLL文件加載到IOC容器中,以下代碼:服務器
foreach (var file in System.IO.Directory.GetFiles(System.IO.Directory.GetCurrentDirectory(), "Trade.*.dll")) { AssemblySource.Instance.Add(Assembly.LoadFile(file)); }
而後經過IOC的方式建立實例網絡
object obj = IoC.Get<IRetrievePwd>(); IoC.Get<IWindowManager>().ShowDialog(obj);
這樣的好處在於:性能
1,項目之間不用互相添加 DLL 文件的引用,作到了鬆耦合。測試
2,經過接口建立對象,實現了程序的多態性。this
3,項目中基本上不會出現new關鍵字,避免了亂建立對象產生的性能損失。對象都給IOC容器管理了。阿里雲
二,普通的代碼引出的問題spa
在開發環境中,個人軟件運行的很順利,在測試環境裏,也沒有發現不能運行的狀況。.net
當軟件打包,發佈到公網的時候,不少用戶反應軟件打不開。
幸運的是在監控日誌中獲得了相關錯誤信息:
An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information.
這個錯誤說的大體意思就是,.net的安全機制阻止了加載一個dll文件。
三,解決方案:
隨後,我在網絡上找到了不少方法,如今彙總一下分享給你們:
方法一:
能夠經過配置文件進行處理
<runtime> <loadFromRemoteSources enabled="true" /> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/> <bindingRedirect oldVersion="0.0.0.0-2.6.8.0" newVersion="2.6.8.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/> <bindingRedirect oldVersion="0.0.0.0-2.6.8.0" newVersion="2.6.8.0"/> </dependentAssembly> </assemblyBinding> </runtime>
相當重要的就是這句:
<loadFromRemoteSources enabled="true" />
方法二:
也能夠經過C#代碼,進行處理
//之前 foreach (var file in System.IO.Directory.GetFiles(System.IO.Directory.GetCurrentDirectory(), "FileTransfer.*.dll")) { AssemblySource.Instance.Add(Assembly.LoadFile(file)); } //替換爲 foreach (var file in System.IO.Directory.GetFiles(System.IO.Directory.GetCurrentDirectory(), "FileTransfer.*.dll")) { AssemblySource.Instance.Add(Assembly.LoadFrom(file)); }
把 Assembly.LoadFile(file) 替換爲 Assembly.LoadFrom(file)
方法三:
仍是經過C#代碼處理,以字節的方式加載DLL
//之前 foreach (var file in System.IO.Directory.GetFiles(System.IO.Directory.GetCurrentDirectory(), "FileTransfer.*.dll")) { AssemblySource.Instance.Add(Assembly.LoadFile(file)); } //替換爲 foreach (var file in System.IO.Directory.GetFiles(System.IO.Directory.GetCurrentDirectory(), "FileTransfer.*.dll")) { byte[] assemblyBuffer = System.IO. File.ReadAllBytes(file); AssemblySource.Instance.Add(Assembly.Load(assemblyBuffer)); }
四:疑問
個人項目一直用 Assembly.LoadFile(file) 加載DLL,在本機上折騰是不會出現問題的。
一旦:
程序以DLL的方式發佈到外網(好比上傳到外網服務器,上傳到阿里雲)
而後:
Download到本地計算機運行,就會報錯,具體錯誤信息,就是我第二大點提到的錯誤信息。
我也仔細對比了上傳前的 DLL 與 經過上傳再下載的DLL,沒有任何區別。包括DLL的屬性設置,讀寫狀態等都沒區別
可是異常就這樣出現了,求緣由,同仁們,大家趕上過這種問題嗎?