//卸载程序集 /// <summary> /// 卸载程序集 /// </summary> /// <param name="dllName"></param> public void Unload(string typeName) { AppDomain domain = null; while (_caches[typeName].Count != 0) { InvokerInfo info = _caches[typeName].Dequeue(); domain = info.Domain; } if (domain != null) { AppDomain.Unload(domain); } }
//尝试卸载程序集 /// <summary> /// 尝试卸载程序集 /// </summary> /// <param name="dllName"></param> /// <param name="currentInfo"></param> private void TryToUnLoad(string dllName, string typeName, InvokerInfo currentInfo) { InvokerInfo info = _caches[typeName].Peek(); if (info == currentInfo) { return; } if (info.Ref == 0) { Unload(typeName); } }
//获取指定程序集的调用信息 /// <summary> /// 获取指定程序集的调用信息 /// </summary> /// <param name="dllName"></param> /// <returns></returns> private InvokerInfo GetInvoker(string dllName, string typeName) { //Get object from cache Queue <InvokerInfo> result; InvokerInfo trueClass = null; _caches.TryGetValue(typeName, out result); foreach (InvokerInfo item in result) { if (item.TypeName == typeName) { trueClass = item; break; } } if (trueClass == null) { throw new Exception(dllName + " not loaded " + typeName); } //Get TimeStamp of file FileInfo info = new FileInfo(AppDomain.CurrentDomain.BaseDirectory + @"ServiceDlls\" + dllName); if (!info.Exists) { return(trueClass); } if (info.LastWriteTime > trueClass.LastWriteTime) { return(CacheMethodInvoker(dllName, typeName, info.LastWriteTime)); } //return result.ToArray()[result.Count - 1]; return(trueClass); }
//缓存指定的方法调用信息 /// <summary> /// 缓存指定的方法调用信息 /// </summary> /// <param name="dllName"></param> /// <param name="typeName"></param> /// <param name="lastWriteTime"></param> /// <returns></returns> private InvokerInfo CacheMethodInvoker(string dllName, string typeName, DateTime lastWriteTime) { MethodInvoker invoker; var invokerInfo = new InvokerInfo(); var setup = new AppDomainSetup { ShadowCopyFiles = "true", ShadowCopyDirectories = AppDomain.CurrentDomain.BaseDirectory + @"ServiceDlls\", ConfigurationFile = "IRAP.DynamicLoad.exe.config", ApplicationBase = AppDomain.CurrentDomain.BaseDirectory }; AppDomain domain = AppDomain.CreateDomain(dllName, null, setup); domain.DoCallBack(delegate { LifetimeServices.LeaseTime = TimeSpan.Zero; }); invokerInfo.Domain = domain; invokerInfo.LastWriteTime = lastWriteTime; invokerInfo.TypeName = typeName; BindingFlags bindings = BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public; object[] para = new object[] { setup.ShadowCopyDirectories + @"\" + dllName, typeName }; try { invoker = (MethodInvoker)domain.CreateInstanceFromAndUnwrap( Assembly.GetExecutingAssembly().CodeBase.Substring(8), typeof(MethodInvoker).FullName, true, bindings, null, para, System.Globalization.CultureInfo.CurrentCulture, null); } catch (Exception ex) { throw new Exception( "Can't create object which type is " + typeof(MethodInvoker).FullName + " from assembly " + Assembly.GetExecutingAssembly().CodeBase + ",Error Message: " + ex.Message); } if (invoker == null) { throw new Exception( "Can't find type " + typeof(MethodInvoker).FullName + " from " + Assembly.GetExecutingAssembly().CodeBase); } try { invoker.LoadAllMethods(); } catch (Exception ex) { throw new Exception("Can't initialize object which type is " + typeof(MethodInvoker).FullName + " from " + Assembly.GetExecutingAssembly().CodeBase + ",Error Message: " + ex.Message); } invokerInfo.Invoker = invoker; invokerInfo.Ref = 0; if (_caches.Keys.Contains(typeName)) { //如果此类缓存中已经存在方法了,说明是过期的,需要重新加载! foreach (InvokerInfo y in _caches[typeName]) { if (y.TypeName == typeName) { _caches[typeName].Clear(); break; } } _caches[typeName].Enqueue(invokerInfo); } else { Queue <InvokerInfo> queue = new Queue <InvokerInfo>(); queue.Enqueue(invokerInfo); _caches[typeName] = queue; } return(invokerInfo); }