示例#1
0
 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.");
 }
示例#2
0
        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);
        }
示例#3
0
 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));
 }
示例#4
0
 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));
         }
     }
 }
示例#5
0
 /// <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.");
 }
示例#6
0
 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);
        }
示例#9
0
        /// <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));
        }
示例#10
0
        /// <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);
        }
示例#11
0
        /// <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);
        }
示例#12
0
 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));
 }
示例#13
0
 private void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs e)
 {
     FileLogUtility.Debug(string.Format(Messages.AssemblyLoadedMessage, e.LoadedAssembly.FullName));
 }
示例#14
0
        /// <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.");
            }
        }
示例#15
0
        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));
                    }
                }
            }
        }
示例#16
0
        /// <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();
            }
        }