예제 #1
0
        /// <summary>
        /// Initializes the class. This includes loading application settings from the configuration file. The application name should be scoped within the system.
        /// For non web applications, this method must be called directly from the main executable assembly and not from a supporting library.
        ///
        /// To debug this method, create a folder called C:\AnyoneFullControl and give Everyone full control. A file will appear in that folder explaining how far
        /// it got in init.
        /// </summary>
        /// <param name="appName"></param>
        /// <param name="isClientSideProgram"></param>
        /// <param name="systemLogic"></param>
        /// <param name="mainDataAccessStateGetter">A method that returns the current main data-access state whenever it is requested, including during this
        /// AppTools.Init call. Do not allow multiple threads to use the same state at the same time. If you pass null, the data-access subsystem will not be
        /// available in the application.</param>
        public static void Init(string appName, bool isClientSideProgram, SystemLogic systemLogic, Func <DataAccessState> mainDataAccessStateGetter = null)
        {
            var initializationLog = "Starting init";

            try {
                if (initialized)
                {
                    throw new ApplicationException("This class can only be initialized once.");
                }

                if (systemLogic == null)
                {
                    throw new ApplicationException("The system must have a global logic class and you must pass an instance of it to AppTools.Init.");
                }

                // Initialize ConfigurationStatics, including the general provider, before the exception handling block below because it's reasonable for the exception
                // handling to depend on this.
                ConfigurationStatics.Init(systemLogic.GetType(), appName, isClientSideProgram, ref initializationLog);

                // Setting the initialized flag to true must be done before executing the secondary init block below so that exception handling works.
                initialized        = true;
                initializationLog += Environment.NewLine + "Succeeded in primary init.";
            }
            catch (Exception e) {
                initializationLog += Environment.NewLine + e;
                StandardLibraryMethods.EmergencyLog("Initialization log", initializationLog);
                throw;
            }

            try {
                var asposeLicense = ConfigurationStatics.SystemGeneralProvider.AsposeLicenseName;
                if (asposeLicense.Any())
                {
                    new Aspose.Pdf.License().SetLicense(asposeLicense);
                    new Aspose.Words.License().SetLicense(asposeLicense);
                }

                // This initialization could be performed using reflection. There is no need for AppTools to have a dependency on these classes.
                AppMemoryCache.Init();
                BlobFileOps.Init();
                DataAccessStatics.Init();
                DataAccessState.Init(mainDataAccessStateGetter);
                EncryptionOps.Init();
                HtmlBlockStatics.Init();
                InstallationSupportUtility.ConfigurationLogic.Init1();
                UserManagementStatics.Init();

                systemLogic.InitSystem();
            }
            catch (Exception e) {
                secondaryInitFailed = true;

                // Suppress all exceptions since they would prevent apps from knowing that primary initialization succeeded. EWF apps need to know this in order to
                // automatically restart themselves. Other apps could find this knowledge useful as well.
                try {
                    EmailAndLogError("An exception occurred during application initialization:", e);
                }
                catch {}
            }
        }
예제 #2
0
        /// <summary>
        /// Call this from Application_Start in your Global.asax.cs file. Besides this call, there should be no other code in the method.
        /// </summary>
        // We could save people the effort of calling this by using trick #1 in
        // http://www.paraesthesia.com/archive/2011/02/08/dynamic-httpmodule-registration-in-asp-net-4-0.aspx, but that would probably require making this a static
        // method and would probably also cause this method to run at start up time in *all* web applications that reference the Standard Library, even the ones
        // that don't want to use EWF.
        protected void ewfApplicationStart(SystemLogic systemLogic)
        {
            // This is a hack to support data-access state in WCF services.
            var wcfDataAccessState = new ThreadLocal <DataAccessState>(() => new DataAccessState());

            // Initialize system.
            var initTimeDataAccessState = new ThreadLocal <DataAccessState>(() => new DataAccessState());

            try {
                AppTools.Init(
                    Path.GetFileName(Path.GetDirectoryName(HttpRuntime.AppDomainAppPath)),
                    false,
                    systemLogic,
                    mainDataAccessStateGetter: () => {
                    // We must use the Instance property here to prevent this logic from always returning the request state of the *first* EwfApp instance.
                    return(Instance != null
                                                               ? Instance.RequestState != null ? Instance.RequestState.DataAccessState : initTimeDataAccessState.Value
                                                               : System.ServiceModel.OperationContext.Current != null ? wcfDataAccessState.Value : null);
                });
            }
            catch {
                // Suppress all exceptions since there is no way to report them.
                return;
            }
            ewlInitialized = true;

            // Initialize web application.
            if (!AppTools.SecondaryInitFailed)
            {
                executeWithBasicExceptionHandling(
                    () => {
                    EwfConfigurationStatics.Init();

                    // Prevent MiniProfiler JSON exceptions caused by pages with hundreds of database queries.
                    MiniProfiler.Settings.MaxJsonResponseSize = int.MaxValue;

                    GlobalType       = GetType().BaseType;
                    MetaLogicFactory =
                        GlobalType.Assembly.CreateInstance("RedStapler.StandardLibrary.EnterpriseWebFramework." + GlobalType.Namespace + ".MetaLogicFactory") as
                        AppMetaLogicFactory;
                    if (MetaLogicFactory == null)
                    {
                        throw new ApplicationException("Meta logic factory not found.");
                    }

                    // This initialization could be performed using reflection. There is no need for EwfApp to have a dependency on these classes.
                    if (systemLogic != null)
                    {
                        CssPreprocessingStatics.Init(systemLogic.GetType().Assembly, GlobalType.Assembly);
                    }
                    else
                    {
                        CssPreprocessingStatics.Init(GlobalType.Assembly);
                    }
                    EwfUiStatics.Init(GlobalType);

                    initializeWebApp();

                    initTimeDataAccessState = null;
                    initialized             = true;
                },
                    false,
                    false);
            }

            // If initialization failed, unload and restart the application after a reasonable delay.
            if (!initialized)
            {
                const int unloadDelay = 60000;                 // milliseconds
                initFailureUnloadTimer = new Timer(
                    state => executeWithBasicExceptionHandling(
                        () => {
                    if (AppTools.IsDevelopmentInstallation)
                    {
                        return;
                    }
                    HttpRuntime.UnloadAppDomain();

                    // Restart the application by making a request. Idea from Rick Strahl:
                    // http://weblog.west-wind.com/posts/2013/Oct/02/Use-IIS-Application-Initialization-for-keeping-ASPNET-Apps-alive.
                    //
                    // Disable server certificate validation so that this request gets through even for web sites that don't use a certificate that is trusted by
                    // default. There is no security risk since we're not sending any sensitive information and we're not using the response.
                    NetTools.ExecuteWithResponse(IisConfigurationStatics.GetFirstBaseUrlForCurrentSite(false), response => { }, disableCertificateValidation: true);
                },
                        false,
                        false),
                    null,
                    unloadDelay,
                    Timeout.Infinite);
            }
        }