来源: .net 动态加载Dll – icyjiang – 博客园
在程序正在使用的过程中,常常需要升级DLL。这时,如果dll已经被主程序引用,则无法修改,这样的需求应该很常见。换个角度,可以理解成程序的升级或者修改Bug的功能。
以下通过动态的加载Dll来解决这个问题。
整个思路的前提是,动态调用的东西和前台需要的功能通过代理IBaseInterface连接起来,也就是说动态dll里面的类和Proxy都需要实现这个接口。
<span class="pln"> </span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">BaseInterface</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">interface</span><span class="pln"> </span><span class="typ">IBaseInterface</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="typ">GetString</span><span class="pun">();</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span> |
核心代码:Proxy.dll
<span class="tag"><pre></span><span class="pln">namespace Proxy { internal class AppDomainCore { public AppDomain DefaultAppDomain { get; private set; } public string DefaultAppDomainName { get; private set; } public AppDomainCore(string appDomainName) { DefaultAppDomainName = appDomainName; AppDomainSetup setup = new AppDomainSetup(); setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; setup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; Evidence evidence = new Evidence(AppDomain.CurrentDomain.Evidence); DefaultAppDomain = AppDomain.CreateDomain(appDomainName, evidence, setup); } public bool ClearAppDomain() { try { AppDomain.Unload(DefaultAppDomain); DefaultAppDomain = null; return true; } catch { return false; } } ~AppDomainCore() { ClearAppDomain(); } } }</span><span class="tag"></pre></span><span class="pln"> </span><span class="tag"><div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"cnblogs_code_toolbar"</span><span class="tag">><span</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"cnblogs_code_copy"</span><span class="tag">><a</span><span class="pln"> </span><span class="atn">title</span><span class="pun">=</span><span class="atv">"复制代码"</span><span class="tag">><img</span><span class="pln"> </span><span class="atn">src</span><span class="pun">=</span><span class="atv">"http://www.mikel.cn/wp-content/uploads/2015/05/copycode30.gif"</span><span class="pln"> </span><span class="atn">alt</span><span class="pun">=</span><span class="atv">"复制代码"</span><span class="pln"> </span><span class="atn">data-bd-imgshare-binded</span><span class="pun">=</span><span class="atv">"1"</span><span class="pln"> </span><span class="tag">/></a></span></span><span class="pln">namespace Proxy { internal class AssemblyCore { public string ActivedAssemblyName { get; private set; } public string CurrentType { get; private set; } public FileInfo DefaultAssemblyFile { get; private set; } public AssemblyCore(string assemblyName, string type) { ActivedAssemblyName = assemblyName; CurrentType = type; try { DefaultAssemblyFile = new FileInfo(assemblyName); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } }</span><span class="tag"></div></span><span class="pln"> </span><span class="tag"><div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"cnblogs_code_toolbar"</span><span class="tag">></div></span><span class="pln"> </span><span class="tag"><div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"cnblogs_code_toolbar"</span><span class="tag">></span><span class="pln">namespace Proxy { public class Proxy : BaseInterface.IBaseInterface { AssemblyCore _assemblyCore; AppDomainCore _appDomainCore; public string DefaultAssemblyName { get { return _assemblyCore.ActivedAssemblyName; } } public string DefaultAppDomainName { get { return _appDomainCore.DefaultAppDomainName; } } public Proxy(string assemblyName, string typeName, string appDomainName) { _assemblyCore = new AssemblyCore(assemblyName, typeName); _appDomainCore = new AppDomainCore(appDomainName); } public void UnLoad() { _appDomainCore.ClearAppDomain(); } BaseInterface.IBaseInterface _proxy; public string GetString() { if (_proxy == null) _proxy = _appDomainCore.DefaultAppDomain.CreateInstanceFromAndUnwrap( _assemblyCore.ActivedAssemblyName, _assemblyCore.CurrentType) as BaseInterface.IBaseInterface; return _proxy.GetString(); } } }</span><span class="tag"></div></span><span class="pln"> </span><span class="tag"><div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"cnblogs_code_toolbar"</span><span class="tag">></span> |