- private void InitializeFactory (HttpContext context)\r
- {\r
- _appFilename = GetAppFilename (context);\r
-\r
- CompileApp (context);\r
-\r
- // Create a application object\r
- HttpApplication app = (HttpApplication) HttpRuntime.CreateInternalObject (_appType);\r
-\r
- // Startup\r
- app.Startup(context, HttpApplicationFactory.ApplicationState);\r
-
- // Shutdown the application if bin directory changes.
- string binFiles = HttpRuntime.BinDirectory;
- if (Directory.Exists (binFiles))
- binFiles = Path.Combine (binFiles, "*.*");
-
- binWatcher = CreateWatcher (binFiles, new FileSystemEventHandler (OnAppFileChanged));
-
- // Fire OnAppStart\r
- HttpApplicationFactory.FireOnAppStart (app);\r
-\r
- // Recycle our application instance\r
- RecyclePublicInstance(app);\r
- }\r
-\r
- private void Dispose() {\r
- ArrayList torelease = new ArrayList();\r
- lock (_appFreePublicList) {\r
- while (_appFreePublicList.Count > 0) {\r
- torelease.Add(_appFreePublicList.Pop());\r
- _appFreePublicInstances--;\r
- }\r
- }\r
-\r
- if (torelease.Count > 0) {\r
- foreach (Object obj in torelease) {\r
- ((HttpApplication) obj).Cleanup();\r
- }\r
- }\r
-\r
- if (!_appFiredEnd) {\r
- lock (this) {\r
- if (!_appFiredEnd) {\r
- FireOnAppEnd();\r
- _appFiredEnd = true;\r
- }\r
- }\r
- }\r
- }\r
-\r
- internal static IHttpHandler GetInstance(HttpContext context)\r
- {\r
- if (custApplication != null)\r
- return custApplication;\r
-\r
- if (!s_Factory._appInitialized) {\r
- lock (s_Factory) {\r
- if (!s_Factory._appInitialized) {\r
- s_Factory.InitializeFactory(context);\r
- s_Factory._appInitialized = true;\r
- }\r
- }\r
- }\r
-\r
- return s_Factory.GetPublicInstance(context);\r
- }\r
-\r
- internal static void RecycleInstance(HttpApplication app) {\r
- if (!s_Factory._appInitialized)\r
- throw new InvalidOperationException("Factory not intialized");\r
-\r
- s_Factory.RecyclePublicInstance(app);\r
- }\r
-\r
- internal static void AttachEvents (HttpApplication app)\r
- {\r
- Hashtable possibleEvents = GetApplicationTypeEvents (app);\r
- foreach (string key in possibleEvents.Keys) {\r
- int pos = key.IndexOf ('_');\r
- if (pos == -1 || key.Length <= pos + 1)\r
- continue;\r
-\r
- string moduleName = key.Substring (0, pos);\r
- object target;\r
- if (moduleName == "Application") {\r
- target = app;\r
- } else {\r
- target = app.Modules [moduleName];\r
- if (target == null)\r
- continue;\r
- }\r
-\r
- string eventName = key.Substring (pos + 1);\r
- EventInfo evt = target.GetType ().GetEvent (eventName);\r
- if (evt == null)\r
- continue;\r
- \r
- string usualName = moduleName + "_" + eventName;\r
- object methodData = possibleEvents [usualName];\r
- if (methodData == null)\r
- continue;\r
-\r
- if (methodData is MethodInfo) {\r
- AddHandler (evt, target, app, (MethodInfo) methodData);\r
- continue;\r
- }\r
-\r
- ArrayList list = (ArrayList) methodData;\r
- foreach (MethodInfo method in list)\r
- AddHandler (evt, target, app, method);\r
- }\r
- }\r
-\r
- static void AddHandler (EventInfo evt, object target, HttpApplication app, MethodInfo method)\r
- {\r
- int length = method.GetParameters ().Length;\r
-\r
- if (length == 0) {\r
- NoParamsInvoker npi = new NoParamsInvoker (app, method.Name);\r
- evt.AddEventHandler (target, npi.FakeDelegate);\r
- } else {\r
- evt.AddEventHandler (target, Delegate.CreateDelegate (\r
- typeof (EventHandler), app, method.Name));\r
- }\r
- }\r
-\r
- private IHttpHandler GetPublicInstance(HttpContext context) {\r
- HttpApplication app = null;\r
-\r
- lock (_appFreePublicList) {\r
- if (_appFreePublicInstances > 0) {\r
- app = (HttpApplication) _appFreePublicList.Pop();\r
- _appFreePublicInstances--;\r
- }\r
- }\r
-\r
- if (app == null) {\r
- // Create non-public object\r
- app = (HttpApplication) HttpRuntime.CreateInternalObject(_appType);\r
-\r
- app.Startup(context, HttpApplicationFactory.ApplicationState);\r
- }\r
-\r
- return (IHttpHandler) app;\r
- }\r
-\r
- internal void RecyclePublicInstance(HttpApplication app) {\r
- lock (_appFreePublicList) {\r
- if (_appFreePublicInstances < _appMaxFreePublicInstances) {\r
- _appFreePublicList.Push(app);\r
- _appFreePublicInstances++;\r
-\r
- app = null;\r
- }\r
- }\r
- \r
- if (app != null) {\r
- app.Cleanup();\r
- }\r
- }\r
-\r
- static HttpStaticObjectsCollection MakeStaticCollection (ArrayList list)\r
- {\r
- if (list == null || list.Count == 0)\r
- return null;\r
-\r
- HttpStaticObjectsCollection coll = new HttpStaticObjectsCollection ();\r
- foreach (ObjectTagBuilder tag in list) {\r
- coll.Add (tag);\r
- }\r
-\r
- return coll;\r
- }\r
- \r
- static internal HttpApplicationState ApplicationState {\r
- get {\r
- if (null == s_Factory._state) {\r
- HttpStaticObjectsCollection app = MakeStaticCollection (GlobalAsaxCompiler.ApplicationObjects);\r
- HttpStaticObjectsCollection ses = MakeStaticCollection (GlobalAsaxCompiler.SessionObjects);\r
- s_Factory._state = new HttpApplicationState (app, ses);\r
- }\r
-\r
- return s_Factory._state;\r
- }\r
- }\r
-\r
- internal static void EndApplication() {\r
- s_Factory.Dispose();\r
- }\r
-\r
- public static void SetCustomApplication (IHttpHandler customApplication)\r
- {\r
- custApplication = customApplication;\r
- }\r
-\r
- internal Type AppType {\r
- get { return _appType; }\r
- }\r
-\r
- internal static void SignalError(Exception exc) {\r
- // TODO: Raise an error (we probably don't have a HttpContext)\r
- }\r
- }\r
-}\r
+ void AddHandler (EventInfo evt, object target, HttpApplication app, MethodInfo method)
+ {
+ int length = method.GetParameters ().Length;
+
+ if (length == 0) {
+ NoParamsInvoker npi = new NoParamsInvoker (app, method.Name);
+ evt.AddEventHandler (target, npi.FakeDelegate);
+ } else {
+ evt.AddEventHandler (target, Delegate.CreateDelegate (
+ typeof (EventHandler), app, method.Name));
+ }
+ }
+
+ static HttpStaticObjectsCollection MakeStaticCollection (ArrayList list)
+ {
+ if (list == null || list.Count == 0)
+ return null;
+
+ HttpStaticObjectsCollection coll = new HttpStaticObjectsCollection ();
+ foreach (ObjectTagBuilder tag in list) {
+ coll.Add (tag);
+ }
+
+ return coll;
+ }
+
+ internal static HttpApplicationState ApplicationState {
+#if TARGET_J2EE
+ get {
+ HttpApplicationFactory factory = theFactory;
+ if (factory.app_state == null)
+ factory.app_state = new HttpApplicationState (null, null);
+ return factory.app_state;
+ }
+#else
+ get {
+ if (theFactory.app_state == null) {
+ HttpStaticObjectsCollection app = MakeStaticCollection (GlobalAsaxCompiler.ApplicationObjects);
+ HttpStaticObjectsCollection ses = MakeStaticCollection (GlobalAsaxCompiler.SessionObjects);
+
+ theFactory.app_state = new HttpApplicationState (app, ses);
+ }
+ return theFactory.app_state;
+ }
+#endif
+ }
+
+ public static void SetCustomApplication (IHttpHandler customApplication)
+ {
+ theFactory.custom_application = customApplication;
+ }
+
+ internal static Type AppType {
+ get {
+ return theFactory.app_type;
+ }
+ }
+
+ void InitType (HttpContext context)
+ {
+ lock (this) {
+ if (!needs_init)
+ return;
+
+ string physical_app_path = context.Request.PhysicalApplicationPath;
+ string app_file;
+
+ app_file = Path.Combine (physical_app_path, "Global.asax");
+ if (!File.Exists (app_file))
+ app_file = Path.Combine (physical_app_path, "global.asax");
+
+ WebConfigurationSettings.Init (context);
+
+ if (File.Exists (app_file)) {
+#if TARGET_J2EE
+ app_type = System.Web.J2EE.PageMapper.GetObjectType(app_file);
+#else
+ app_type = ApplicationFileParser.GetCompiledApplicationType (app_file, context);
+ if (app_type == null) {
+ string msg = String.Format ("Error compiling application file ({0}).", app_file);
+ throw new ApplicationException (msg);
+ }
+
+ app_file_watcher = CreateWatcher (app_file, new FileSystemEventHandler (OnAppFileChanged));
+#endif
+ } else {
+ app_type = typeof (System.Web.HttpApplication);
+ app_state = new HttpApplicationState ();
+ }
+ needs_init = false;
+
+ //
+ // Now init the settings
+ //
+
+ }
+ }
+
+ //
+ // Multiple-threads might hit this one on startup, and we have
+ // to delay-initialize until we have the HttpContext
+ //
+ internal static HttpApplication GetApplication (HttpContext context)
+ {
+ HttpApplicationFactory factory = theFactory;
+ if (factory.needs_init){
+ if (context == null)
+ return null;
+
+ factory.InitType (context);
+ factory.FireOnAppStart (context);
+ }
+
+ lock (factory) {
+ if (factory.available.Count > 0)
+ return (HttpApplication) factory.available.Pop ();
+ }
+
+ HttpApplication app = (HttpApplication) Activator.CreateInstance (factory.app_type, true);
+
+ return app;
+ }
+
+ internal static void Recycle (HttpApplication app)
+ {
+ HttpApplicationFactory factory = theFactory;
+ lock (factory) {
+ if (factory.available.Count < 32)
+ factory.available.Push (app);
+ else
+ app.Dispose ();
+ }
+ }
+ }
+}