public virtual void StartBundleRuntime() { FileLogUtility.Debug("WebSite is starting."); AddPreDefinedRefAssemblies(); AppDomain.CurrentDomain.SetData("SQLServerCompactEditionUnderWebHosting", true); BundleRuntime = CreateBundleRuntime(); BundleRuntime.Instance.Framework.EventManager.AddBundleEventListener(new EventHandler <BundleStateChangedEventArgs>( BundleRuntimeHttpHostHelper.RefreshBundleTopLevelReferencedAssembliesByEvent), true); FileLogUtility.Debug("Framework is starting."); BundleRuntime.Start(); ControllerBuilder.Current.SetControllerFactory(new BundleRuntimeControllerFactory()); RegisterGlobalFilters(GlobalFilters.Filters); FileLogUtility.Debug("Framework is started."); }
public void StartBundleRuntime() { FileLogUtility.SetLogLevel(LogLevel); FileLogUtility.SetMaxFileSizeByMB(MaxLogFileSize); FileLogUtility.SetCreateNewFileOnMaxSize(CreateNewLogFileOnMaxSize); FileLogUtility.Debug("WebSite is starting."); PropertyInfo buildManagerProp = typeof(BuildManager).GetProperty("TheBuildManager", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetProperty); if (buildManagerProp != null) { BuildManager buildManager = buildManagerProp.GetValue(null, null) as BuildManager; if (buildManager != null) { PropertyInfo toplevelAssembliesProp = typeof(BuildManager).GetProperty("TopLevelReferencedAssemblies", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty); if (toplevelAssembliesProp != null) { _topLevelReferencedAssemblies = toplevelAssembliesProp.GetValue(buildManager, null) as IList <Assembly>; } } } if (_topLevelReferencedAssemblies == null) { throw new Exception("Retrieve top level referenced assembiles of BuildManager failed."); } AddPreDefinedRefAssemblies(); // Set SQLCE compact before BundleRuntime starting. AppDomain.CurrentDomain.SetData("SQLServerCompactEditionUnderWebHosting", true); InitPhysicalPaths(); BundleRuntime = CreateBundleRuntime(); BundleRuntime.Instance.Framework.EventManager.AddBundleEventListener(BundleEventListener, true); FileLogUtility.Debug("Framework is starting."); StateTimeoutToRestart(BundleRuntimeState.Started); BundleRuntime.Start(); FileLogUtility.Debug("Framework is started."); FileLogUtility.Debug("WebSite is started."); ControllerBuilder.Current.SetControllerFactory(new BundleRuntimeControllerFactory()); RegisterGlobalFilters(GlobalFilters.Filters); }
public virtual void Uninstall() { if (IsActive) { try { Stop(BundleStopOptions.Transient); } catch (Exception exception) { FileLogUtility.Error(string.Format(Messages.ExceptionOccursWhenUninstalling, SymbolicName, Version)); FileLogUtility.Error(exception); } } FileLogUtility.Debug(string.Format(Messages.BundleUninstalling, SymbolicName, Version)); DoLifecycleAction(() => DoUninstall(), Messages.UninstallAction); FileLogUtility.Debug(string.Format(Messages.BundleInState, SymbolicName, Version, State)); }
public static void RemoveReferencedAssemblies(BundleData bundleData) { using (ReaderWriterLockHelper.CreateReaderLock(_cacheLock)) { if (_registeredBunldeCache.ContainsKey(bundleData)) { IList <Assembly> removedAssemblies = _registeredBunldeCache[bundleData]; using (ReaderWriterLockHelper.CreateWriterLock(_cacheLock)) { _registeredBunldeCache.Remove(bundleData); } ResetTopLevelReferencedAssemblies(removedAssemblies); FileLogUtility.Debug( string.Format("Remove the assemblies of bundle '{0}' from top level referenced assemblies since the bundle is stopping.", bundleData.SymbolicName)); } } }
/// <summary> /// 应用启动时处理函数。该函数用于初始化TopLevelReferncedAssemblies,并将UIShell.OSGi和UIShell.OSGi.WebExtension这两个程序集添加到该属性。 /// 同时,启动Bundle运行时。 /// </summary> /// <param name="sender">Sender。</param> /// <param name="e">事件参数。</param> protected virtual void Application_Start(object sender, EventArgs e) { FileLogUtility.Init(LogName, LogLocation); FileLogUtility.SetLogLevel(LogLevel); FileLogUtility.SetMaxFileSizeByMB(MaxLogFileSize); FileLogUtility.SetCreateNewFileOnMaxSize(CreateNewLogFileOnMaxSize); FileLogUtility.Debug("WebSite is starting."); AddPreDefinedRefAssemblies(); AppDomain.CurrentDomain.SetData("SQLServerCompactEditionUnderWebHosting", true); BundleRuntime = CreateBundleRuntime(); BundleRuntime.Instance.Framework.EventManager.AddBundleEventListener( new EventHandler <BundleStateChangedEventArgs>(BundleRuntimeHttpHostHelper.RefreshBundleTopLevelReferencedAssembliesByEvent), true); FileLogUtility.Debug("Framework is starting."); StateTimeoutToRestart(BundleRuntimeState.Started); BundleRuntime.Start(); FileLogUtility.Debug("Framework is started."); FileLogUtility.Debug("WebSite is started."); }
public static void AddReferencedAssemblies(BundleData bundleData) { using (ReaderWriterLockHelper.CreateReaderLock(_cacheLock)) { if (!_registeredBunldeCache.ContainsKey(bundleData)) { IList <Assembly> list = AddReferencedAssemblies(bundleData.SymbolicName); FileLogUtility.Debug( string.Format("Add the assemblies of bundle '{0}' to top level referenced assemblies since the bundle is active.", bundleData.SymbolicName)); if (list != null && list.Count > 0) { using (ReaderWriterLockHelper.CreateWriterLock(_cacheLock)) { _registeredBunldeCache[bundleData] = list; } } } } }
private void LoadBundleResources() { foreach (var bundle in BundleRuntime.Framework.Bundles) { var bundleData = BundleRuntime.Instance.GetFirstOrDefaultService <IBundleInstallerService>() .GetBundleDataByName(bundle.SymbolicName); if (bundleData == null) { continue; } //register bundle assemblies to BuildManager. var assemblies = AddReferencedAssemblies(bundleData.SymbolicName); FileLogUtility.Debug(string.Format("Loaded assembiles from bundle {0}", bundle.SymbolicName)); if (assemblies != null && assemblies.Count > 0) { RegisteredBunldeCache[bundleData] = assemblies; } } }
public void StartBundleRuntime() { FileLogUtility.Debug("WebSite is starting."); AddPreDefinedRefAssemblies(); // Set SQLCE compact before BundleRuntime starting. AppDomain.CurrentDomain.SetData("SQLServerCompactEditionUnderWebHosting", true); BundleRuntime = CreateBundleRuntime(); FileLogUtility.Debug("Framework is starting."); BundleRuntime.Start(); //force to start all plugins LoadBundleResources(); FileLogUtility.Debug("Framework is started."); ControllerBuilder.Current.SetControllerFactory(new BundleRuntimeControllerFactory()); RegisterGlobalFilters(GlobalFilters.Filters); }
/// <summary> /// 将Assembly添加到ASP.NET页面预编译引用程序集列表。这个方法一般是内部使用。 /// </summary> /// <param name="assembly">程序集对象。</param> public void AddReferencedAssembly(Assembly assembly) { // TODO:在以下场景会出现一些问题,场景描述为:WebHost程序引用了 // 插件Service的程序集,这个程序集在编译时会拷贝到bin目录下。 // // 此时,该程序集在CLR路径中可以加载到,但是这个程序集 // 又被服务插件添加到TopReferencedAssemblies,此时在编译时会提示 // 一个重复程序集异常。 // // 如果,我们在这里面进行判断是否CLR可以加载到时,又会有另一个异常, // 即WebHost的程序集是由CLR加载的,但是服务插件的程序集是由Assembly.LoadFile // 加载的,因此服务插件注册的服务接口是使用Assembly.LoadFile来定义, // 因此在WebHost用CLR加载的同一个程序集的接口去访问服务则无法访问到。 // //Assembly asmInClrLoader = null; //try //{ // asmInClrLoader = Assembly.Load(assembly.FullName); //} //catch { } //if (asmInClrLoader != null) //{ // FileLogUtility.Warn(string.Format("There is a assembly '{0}' can be loaded by CLR loader and it is ignored to add to top level assembly reference.", assembly.FullName)); // return; //} // TODO: 性能优化 using (ReaderWriterLockHelper.CreateWriterLock(RefAssembliesLock)) { if (TopLevelReferencedAssemblies.Any(tempAssembly => tempAssembly.FullName.Equals(assembly.FullName))) { return; } TopLevelReferencedAssemblies.Add(assembly); } FileLogUtility.Debug(string.Format("Add assembly '{0} to top level referenced assemblies.'", assembly.FullName)); }
/// <summary> /// 将插件本地程序集添加到ASP.NET页面预编译引用程序集列表。这个方法一般是内部使用。 /// </summary> /// <param name="bundleSymbolicName">插件唯一名称。</param> /// <returns>返回插件所有本地程序集。</returns> public static IList <Assembly> AddReferencedAssemblies(string bundleSymbolicName) { BundleData bundleDataByName = BundleRuntime.Instance.GetFirstOrDefaultService <IBundleInstallerService>().GetBundleDataByName(bundleSymbolicName); if (bundleDataByName == null) { FileLogUtility.Debug(string.Format("Bundle '{0}' does not exist when trying to add its assemblies to referenced assemblies.", bundleSymbolicName)); return(new List <Assembly>()); } IList <Assembly> result; using (ReaderWriterLockHelper.CreateReaderLock(_cacheLock)) { IList <Assembly> list; if (_registeredBunldeCache.TryGetValue(bundleDataByName, out list)) { result = list; } else { IServiceManager serviceContainer = BundleRuntime.Instance.Framework.ServiceContainer; IRuntimeService firstOrDefaultService = serviceContainer.GetFirstOrDefaultService <IRuntimeService>(); List <Assembly> list2 = firstOrDefaultService.LoadBundleAssembly(bundleSymbolicName); FileLogUtility.Debug(string.Format("Add the assemblies of bundle '{0}' to top level referenced assemblies.", bundleSymbolicName)); using (ReaderWriterLockHelper.CreateWriterLock(_cacheLock)) { _registeredBunldeCache[bundleDataByName] = list2; } ResetTopLevelReferencedAssemblies(null); result = list2; } } return(result); }
/// <summary> /// 注册组件 /// </summary> /// <param name="location">位置</param> /// <param name="bd">组件数据</param> /// <returns>IBundle</returns> public IBundle InstallBundle(string location, BundleData bd) { if (!ValidExtention(location)) { location = location + BundleExtention; } string fullLocation = string.Empty; bool isPathRooted = Path.IsPathRooted(location); if (isPathRooted) { fullLocation = location; } if (!File.Exists(fullLocation)) { FileLogUtility.Debug(string.Format("{0}: Bundle {0} not found. {1}", location, DateTime.Now)); FileLogUtility.Debug(string.Format("{0}: file:{0} not found. {1}", fullLocation, DateTime.Now)); } // Create the bundle object BundleData bundleData = bd; bundleData.Id = _bundleRepository.Count; bundleData.Location = fullLocation; Bundle bundle = new Bundle(bundleData, this); if (CheckInstallBundle(bundle)) { InstallBundleInternal(bundle); } return(bundle); }
public virtual void Stop(BundleStopOptions option) { FileLogUtility.Debug(string.Format(Messages.BundleStopping, SymbolicName, Version)); DoLifecycleAction(() => DoStop(option), Messages.StopAction); FileLogUtility.Debug(string.Format(Messages.BundleInState, SymbolicName, Version, State)); }
private void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs e) { FileLogUtility.Debug(string.Format(Messages.AssemblyLoadedMessage, e.LoadedAssembly.FullName)); }
/// <summary> /// 重启ASP.NET应用域,包括BundleRuntime。当卸载一个模块或者更新一个模块时,需要重新启动应用域,因为旧的程序集会一直保留在BundleRuntime所在应用域直到应用域重启。 /// </summary> public virtual void RestartAppDomain(WriteHtmlContentAfterReboot writeHtmlContent) { FileLogUtility.Debug("Restarting the website by write bin forder or web config."); bool success = TryWriteBinFolder() || TryWriteWebConfig(); if (!success) { throw new BundleException( string.Format("UIShell.OSGi needs to be restarted due to bundle uninstalling or updating, but was unable to do so.\r\n" + "To prevent this issue in the future, a change to the web server configuration is required:\r\n" + "- run the application in a full trust environment, or\r\n" + "- give the application write access to the '{0}' folder, or\r\n" + "- give the application write access to the '{1}' file.", _hostRestartPhysicalPath, _webConfigPhysicalPath)); } // If setting up extensions/modules requires an AppDomain restart, it's very unlikely the // current request can be processed correctly. So, we redirect to the same URL, so that the // new request will come to the newly started AppDomain. HttpContext httpContext = HttpContext.Current; if (httpContext != null) { // Don't redirect posts... if (httpContext.Request.RequestType == "GET") { httpContext.Response.Redirect(httpContext.Request.Url.ToString(), true /*endResponse*/); } else { string refreshHtmlFullPath = _refreshHtmlPhysicalPath; try { // AppStore will create a refresh.html with different content. if (File.Exists(refreshHtmlFullPath)) { File.Delete(refreshHtmlFullPath); } using (StreamWriter sw = File.CreateText(refreshHtmlFullPath)) { if (writeHtmlContent != null) { writeHtmlContent(sw); } } } catch { throw new BundleException( string.Format("UIShell.OSGi needs to be restarted due to bundle uninstalling or updating, but was unable to do so.\r\n" + "To prevent this issue in the future, a change to the web server configuration is required:\r\n" + "- give the application create/write access to the '{0}' file.", refreshHtmlFullPath)); } httpContext.Response.WriteFile(_refreshHtmlPhysicalPath); httpContext.Response.End(); } FileLogUtility.Debug("Restart website successfully."); } }
private void BundleEventListener(object sender, BundleStateChangedEventArgs args) { // This is in another domain, thus the HttpContext.Current is always null. // Just comment it. //if (HttpContext.Current == null) //{ // return; //} //check if this bundle still exist. BundleData bundleData = BundleRuntime.Instance.GetFirstOrDefaultService <IBundleInstallerService>() .GetBundleDataByName(args.Bundle.SymbolicName); if (bundleData == null) { return; } bool needLoad = (args.CurrentState == BundleState.Active); if (needLoad) { //already registered its assemblies using (ReaderWriterLockHelper.CreateReaderLock(CacheLock)) { if (RegisteredBunldeCache.ContainsKey(bundleData)) { return; } //register bundle assemblies to BuildManager. ICollection <Assembly> assemblies = AddReferencedAssemblies(bundleData.SymbolicName); FileLogUtility.Debug( string.Format("Add the assemblies of bundle '{0}' to top level referenced assemblies since the bundle is active.", args.Bundle.SymbolicName)); if (assemblies != null && assemblies.Count > 0) { using (ReaderWriterLockHelper.CreateWriterLock(CacheLock)) { RegisteredBunldeCache[bundleData] = assemblies; } } } } else if (args.CurrentState == BundleState.Stopping) { //unregister when stopping. using (ReaderWriterLockHelper.CreateReaderLock(CacheLock)) { if (RegisteredBunldeCache.ContainsKey(bundleData)) { RemoveReferencedAssemblies(RegisteredBunldeCache[bundleData]); //remove from cache. using (ReaderWriterLockHelper.CreateWriterLock(CacheLock)) { RegisteredBunldeCache.Remove(bundleData); } FileLogUtility.Debug( string.Format("Remove the assemblies of bundle '{0}' from top level referenced assemblies since the bundle is stopping.", args.Bundle.SymbolicName)); } } } }
/// <summary> /// 将插件的一个ASP.NET页面编译并构建成一个IHttpHandler实例。 /// </summary> /// <param name="context">HttpContext。</param> /// <param name="requestType">请求类型。</param> /// <param name="virtualPath">页面虚拟路径。</param> /// <param name="path">页面物理路径。</param> /// <returns>IHttpHandler实例。</returns> public override IHttpHandler GetHandler(HttpContext context, string requestType, string virtualPath, string path) { BundleRuntime instance = BundleRuntime.Instance; if (instance.State != BundleRuntimeState.Started) { try { FileLogUtility.Debug(string.Format("Framework is not in 'Started' state when access page '{0}'.", path)); return(base.GetHandler(context, requestType, FrameworkBusyHandlerPage, "")); } catch (Exception ex) { FileLogUtility.Warn("Failed to redirect framework Busy Handler page when Framework is not in 'Started'."); FileLogUtility.Warn(ex); } return(null); } string value = string.Empty; IBundleRuntimeHttpHost bundleRuntimeHttpHost = (IBundleRuntimeHttpHost)context.ApplicationInstance; BundleData bundleData = bundleRuntimeHttpHost.BundleRuntime.GetFirstOrDefaultService <IBundleInstallerService>() .FindBundleContainPath(Directory.GetParent(path).FullName); if (bundleData != null) { value = bundleData.SymbolicName; } if (string.IsNullOrEmpty(value)) { FileLogUtility.Debug(string.Format( "Failed to get the bundle contains requested page '{0}' and just compile this page into IHttpHandler. Just compile the page directly.", path)); return(SafelyGetHandler(context, requestType, virtualPath, path)); } IBundle bundle = bundleRuntimeHttpHost.BundleRuntime.Framework.GetBundle(bundleData.Path); if (bundle == null) { return(SafelyGetHandler(context, requestType, virtualPath, path)); } FileLogUtility.Debug(string.Format("The bundle state of requested page '{0}' is '{1}'.", path, bundle.State)); switch (bundle.State) { case BundleState.Installed: case BundleState.Resolved: { object syncObject; Monitor.Enter(syncObject = _syncObject); try { bundle.Start(BundleStartOptions.General); bundleRuntimeHttpHost.AddReferencedAssemblies(bundleData.SymbolicName); } finally { Monitor.Exit(syncObject); } return(SafelyGetHandler(context, requestType, virtualPath, path)); } case BundleState.Starting: { object syncObject2; Monitor.Enter(syncObject2 = _syncObject); try { bundleRuntimeHttpHost.AddReferencedAssemblies(bundleData.SymbolicName); } finally { Monitor.Exit(syncObject2); } return(SafelyGetHandler(context, requestType, virtualPath, path)); } case BundleState.Active: return(SafelyGetHandler(context, requestType, virtualPath, path)); case BundleState.Stopping: return(HandleException(context, requestType, new HttpException("Access denied, for the bundle is stopping."))); case BundleState.Uninstalled: return(HandleException(context, requestType, new HttpException("Access denied, for the bundle is uninstalled."))); default: throw new NotSupportedException(); } }