一,普通的一段代码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的属性设置,读写状态等都没区别
可是异常就这样出现了,求缘由,同仁们,大家赶上过这种问题吗?