Browse Source

[asp.net] Implemented undocumented BuildManagerHost class to support the Cassini ASP.NET host

Marek Habersack 14 years ago
parent
commit
b76dfd8cea

+ 54 - 0
mcs/class/System.Web/System.Web.Compilation/BuildManagerHost.cs

@@ -0,0 +1,54 @@
+//
+// Authors:
+//      Marek Habersack <[email protected]>
+//
+// (C) 2011 Novell, Inc (http://novell.com)
+//
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Concurrent;
+using System.Web;
+using System.Web.Hosting;
+
+namespace System.Web.Compilation
+{
+	class BuildManagerHost : MarshalByRefObject, IRegisteredObject
+	{
+		// This method is used by the Cassini ASP.NET host application (and all of its
+		// derivatives, e.g. CassiniDev, see http://cassinidev.codeplex.com) to register the
+		// host assembly with System.Web's assembly resolver in order to enable loading
+		// types from assemblies not installed in GAC.
+		//
+		protected void RegisterAssembly (string assemblyName, string assemblyLocation)
+		{
+			if (String.IsNullOrEmpty (assemblyName) || String.IsNullOrEmpty (assemblyLocation))
+				return;
+
+			HttpRuntime.RegisteredAssemblies.InsertOrUpdate ((uint)assemblyName.GetHashCode (), assemblyName, assemblyLocation, assemblyLocation);
+			HttpRuntime.EnableAssemblyMapping (true);
+		}
+
+		public void Stop (bool immediate)
+		{}
+	}
+}

+ 1 - 0
mcs/class/System.Web/System.Web.dll.sources

@@ -50,6 +50,7 @@ System.Web.Compilation/AssemblyBuilder.cs
 System.Web.Compilation/BaseCompiler.cs
 System.Web.Compilation/BuildDependencySet.cs
 System.Web.Compilation/BuildManager.cs
+System.Web.Compilation/BuildManagerHost.cs
 System.Web.Compilation/BuildManagerCacheItem.cs
 System.Web.Compilation/BuildManagerDirectoryBuilder.cs
 System.Web.Compilation/BuildManagerRemoveEntryEventHandler.cs

+ 25 - 12
mcs/class/System.Web/System.Web/HttpRuntime.cs

@@ -35,6 +35,7 @@ using System.IO;
 using System.Text;
 using System.Globalization;
 using System.Collections;
+using System.Collections.Concurrent;
 using System.Reflection;
 using System.Security;
 using System.Security.Permissions;
@@ -61,7 +62,7 @@ namespace System.Web
 	public sealed class HttpRuntime
 	{
 		static bool domainUnloading;
-		
+		static SplitOrderedList <string, string> registeredAssemblies;
 #if TARGET_J2EE
 		static QueueManager queue_manager { get { return _runtime._queue_manager; } }
 		static TraceManager trace_manager { get { return _runtime._trace_manager; } }
@@ -153,6 +154,7 @@ namespace System.Web
 			if (trace_manager.HasException)
 					initialException = trace_manager.InitialException;
 
+			registeredAssemblies = new SplitOrderedList <string, string> (StringComparer.Ordinal);
 			cache = new Cache ();
 			internalCache = new Cache ();
 			internalCache.DependencyCache = internalCache;
@@ -164,6 +166,10 @@ namespace System.Web
 				});
 			end_of_send_cb = new HttpWorkerRequest.EndOfSendNotification (EndOfSend);
 		}
+
+		internal static SplitOrderedList <string, string> RegisteredAssemblies {
+			get { return registeredAssemblies; }
+		}
 		
 #region AppDomain handling
 		internal static bool DomainUnloading {
@@ -706,22 +712,29 @@ namespace System.Web
 			AssemblyName an = new AssemblyName (e.Name);
 			string dynamic_base = AppDomain.CurrentDomain.SetupInformation.DynamicBase;
 			string compiled = Path.Combine (dynamic_base, an.Name + ".compiled");
+			string asmPath;
 
-			if (!File.Exists (compiled))
-				return null;
-
-			PreservationFile pf;
-			try {
-				pf = new PreservationFile (compiled);
-			} catch (Exception ex) {
-				throw new HttpException (
-					String.Format ("Failed to read preservation file {0}", an.Name + ".compiled"),
-					ex);
+			if (!File.Exists (compiled)) {
+				string fn = an.FullName;
+				if (!RegisteredAssemblies.Find ((uint)fn.GetHashCode (), fn, out asmPath))
+					return null;
+			} else {
+				PreservationFile pf;
+				try {
+					pf = new PreservationFile (compiled);
+				} catch (Exception ex) {
+					throw new HttpException (
+						String.Format ("Failed to read preservation file {0}", an.Name + ".compiled"),
+						ex);
+				}
+				asmPath = Path.Combine (dynamic_base, pf.Assembly + ".dll");
 			}
+
+			if (String.IsNullOrEmpty (asmPath))
+				return null;
 			
 			Assembly ret = null;
 			try {
-				string asmPath = Path.Combine (dynamic_base, pf.Assembly + ".dll");
 				ret = Assembly.LoadFrom (asmPath);
 			} catch (Exception) {
 				// ignore