//
using System;
using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Reflection;
-
-#if NET_2_0
-using System.Collections.Generic;
using System.Web;
using System.Web.Configuration;
using System.Web.UI;
-#endif
+using System.Web.Util;
namespace System.Web.Compilation
{
- internal class AspComponentFoundry
+ class AspComponentFoundry
{
- private Hashtable foundries;
-
+ Hashtable foundries;
+ Dictionary <string, AspComponent> components;
+ Dictionary <string, AspComponent> Components {
+ get {
+ if (components == null)
+ components = new Dictionary <string, AspComponent> (StringComparer.OrdinalIgnoreCase);
+ return components;
+ }
+ }
+
public AspComponentFoundry ()
{
-#if NET_2_0
foundries = new Hashtable (StringComparer.InvariantCultureIgnoreCase);
-#else
- foundries = new Hashtable (CaseInsensitiveHashCodeProvider.DefaultInvariant,
- CaseInsensitiveComparer.DefaultInvariant);
-#endif
-
Assembly sw = typeof (AspComponentFoundry).Assembly;
RegisterFoundry ("asp", sw, "System.Web.UI.WebControls");
RegisterFoundry ("", "object", typeof (System.Web.UI.ObjectTag));
-
-#if NET_2_0
RegisterConfigControls ();
-#endif
}
- public Type GetComponentType (string foundryName, string tag)
+ public AspComponent GetComponent (string tagName)
{
- Foundry foundry = foundries [foundryName] as Foundry;
- if (foundry == null)
+ if (tagName == null || tagName.Length == 0)
+ return null;
+
+ if (components != null) {
+ AspComponent ret;
+ if (components.TryGetValue (tagName, out ret))
+ return ret;
+ }
+
+ string foundryName, tag;
+ int colon = tagName.IndexOf (':');
+ if (colon > -1) {
+ if (colon == 0)
+ throw new Exception ("Empty TagPrefix is not valid.");
+ if (colon + 1 == tagName.Length)
+ return null;
+ foundryName = tagName.Substring (0, colon);
+ tag = tagName.Substring (colon + 1);
+ } else {
+ foundryName = String.Empty;
+ tag = tagName;
+ }
+
+ object o = foundries [foundryName];
+ if (o == null)
+ return null;
+
+ Foundry foundry = o as Foundry;
+ if (foundry != null)
+ return CreateComponent (foundry, tagName, foundryName, tag);
+
+ ArrayList af = o as ArrayList;
+ if (af == null)
return null;
- return foundry.GetType (tag);
+ AspComponent component = null;
+ Exception e = null;
+ foreach (Foundry f in af) {
+ try {
+ component = CreateComponent (f, tagName, foundryName, tag);
+ if (component != null)
+ return component;
+ } catch (Exception ex) {
+ e = ex;
+ }
+ }
+
+ if (e != null)
+ throw e;
+
+ return null;
}
+ AspComponent CreateComponent (Foundry foundry, string tagName, string prefix, string tag)
+ {
+ string source, ns;
+ Type type;
+
+ type = foundry.GetType (tag, out source, out ns);
+ if (type == null)
+ return null;
+
+ AspComponent ret = new AspComponent (type, ns, prefix, source, foundry.FromConfig);
+ Dictionary <string, AspComponent> components = Components;
+ components.Add (tagName, ret);
+ return ret;
+ }
+
+ public void RegisterFoundry (string foundryName, Assembly assembly, string nameSpace)
+ {
+ RegisterFoundry (foundryName, assembly, nameSpace, false);
+ }
+
public void RegisterFoundry (string foundryName,
- Assembly assembly,
- string nameSpace)
+ Assembly assembly,
+ string nameSpace,
+ bool fromConfig)
{
AssemblyFoundry foundry = new AssemblyFoundry (assembly, nameSpace);
- InternalRegister (foundryName, foundry);
+ foundry.FromConfig = fromConfig;
+ InternalRegister (foundryName, foundry, fromConfig);
}
+ public void RegisterFoundry (string foundryName, string tagName, Type type)
+ {
+ RegisterFoundry (foundryName, tagName, type, false);
+ }
+
public void RegisterFoundry (string foundryName,
- string tagName,
- Type type)
+ string tagName,
+ Type type,
+ bool fromConfig)
{
TagNameFoundry foundry = new TagNameFoundry (tagName, type);
- InternalRegister (foundryName, foundry);
+ foundry.FromConfig = fromConfig;
+ InternalRegister (foundryName, foundry, fromConfig);
}
-#if NET_2_0
- public void RegisterFoundry (string foundryName,
- string tagName,
- string source)
+ public void RegisterFoundry (string foundryName, string tagName, string source)
{
- TagNameFoundry foundry = new TagNameFoundry (tagName, source);
- InternalRegister (foundryName, foundry);
+ RegisterFoundry (foundryName, tagName, source, false);
}
- // Look up the controls/namespaces defined in the config
- // file(s), resolve the assemblies but do not compile the types.
- void RegisterConfigControls ()
+ public void RegisterFoundry (string foundryName,
+ string tagName,
+ string source,
+ bool fromConfig)
{
- PagesSection pages = WebConfigurationManager.GetSection ("system.web/pages") as PagesSection;
- if (pages == null)
- return;
-
- TagPrefixCollection controls = pages.Controls;
- if (controls == null || controls.Count == 0)
- return;
-
- Dictionary <string, Assembly> assemblyCache = new Dictionary <string, Assembly> ();
- foreach (TagPrefixInfo tpi in controls) {
- if (!String.IsNullOrEmpty (tpi.TagName))
- RegisterFoundry (tpi.TagPrefix, tpi.TagName, tpi.Source);
- else if (!String.IsNullOrEmpty (tpi.Namespace))
- RegisterFoundry (tpi.TagPrefix, GetAssemblyByName (assemblyCache, tpi.Assembly), tpi.Namespace);
- }
+ TagNameFoundry foundry = new TagNameFoundry (tagName, source);
+ foundry.FromConfig = fromConfig;
+ InternalRegister (foundryName, foundry, fromConfig);
}
- Assembly GetAssemblyByName (Dictionary <string, Assembly> cache, string name)
+ public void RegisterAssemblyFoundry (string foundryName,
+ string assemblyName,
+ string nameSpace,
+ bool fromConfig)
{
- if (cache.ContainsKey (name))
- return cache [name];
+ AssemblyFoundry foundry = new AssemblyFoundry (assemblyName, nameSpace);
+ foundry.FromConfig = fromConfig;
+ InternalRegister (foundryName, foundry, fromConfig);
+ }
- Assembly assembly = null;
- Exception error = null;
- if (name.IndexOf (',') != -1) {
- try {
- assembly = Assembly.Load (name);
- } catch (Exception e) { error = e; }
- }
+ void RegisterConfigControls ()
+ {
+ PagesSection pages = WebConfigurationManager.GetSection ("system.web/pages") as PagesSection;
+ if (pages == null)
+ return;
- if (assembly == null) {
- try {
- assembly = Assembly.LoadWithPartialName (name);
- } catch (Exception e) { error = e; }
- }
+ TagPrefixCollection controls = pages.Controls;
+ if (controls == null || controls.Count == 0)
+ return;
- if (assembly == null)
- throw new HttpException ("Assembly " + name + " not found", error);
-
- return assembly;
+ IList appCode = BuildManager.CodeAssemblies;
+ bool haveCodeAssemblies = appCode != null && appCode.Count > 0;
+ Assembly asm;
+ foreach (TagPrefixInfo tpi in controls) {
+ if (!String.IsNullOrEmpty (tpi.TagName))
+ RegisterFoundry (tpi.TagPrefix, tpi.TagName, tpi.Source, true);
+ else if (String.IsNullOrEmpty (tpi.Assembly)) {
+ if (haveCodeAssemblies) {
+ foreach (object o in appCode) {
+ asm = o as Assembly;
+ if (asm == null)
+ continue;
+ RegisterFoundry (tpi.TagPrefix, asm, tpi.Namespace, true);
+ }
+ }
+ } else if (!String.IsNullOrEmpty (tpi.Namespace))
+ RegisterAssemblyFoundry (tpi.TagPrefix,
+ tpi.Assembly,
+ tpi.Namespace,
+ true);
+ }
}
-#endif
- void InternalRegister (string foundryName, Foundry foundry)
+ void InternalRegister (string foundryName, Foundry foundry, bool fromConfig)
{
object f = foundries [foundryName];
+ Foundry newFoundry = null;
+
if (f is CompoundFoundry) {
((CompoundFoundry) f).Add (foundry);
- } else if (f == null || (f is AssemblyFoundry && foundry is AssemblyFoundry)) {
- // If more than 1 namespace/assembly specified, the last one is used.
- foundries [foundryName] = foundry;
+ return;
+ } else if (f == null || f is ArrayList || (f is AssemblyFoundry && foundry is AssemblyFoundry)) {
+ newFoundry = foundry;
} else if (f != null) {
CompoundFoundry compound = new CompoundFoundry (foundryName);
compound.Add ((Foundry) f);
compound.Add (foundry);
- foundries [foundryName] = compound;
+ newFoundry = foundry;
+ newFoundry.FromConfig = fromConfig;
+ }
+
+ if (newFoundry == null)
+ return;
+
+ if (f == null) {
+ foundries [foundryName] = newFoundry;
+ return;
}
+
+ ArrayList af = f as ArrayList;
+ if (af == null) {
+ af = new ArrayList (2);
+ af.Add (f);
+ foundries [foundryName] = af;
+ }
+
+ if (newFoundry is AssemblyFoundry) {
+ object o;
+ for (int i = 0; i < af.Count; i++) {
+ o = af [i];
+ if (o is AssemblyFoundry) {
+ af.Insert (i, newFoundry);
+ return;
+ }
+ }
+ af.Add (newFoundry);
+ } else
+ af.Insert (0, newFoundry);
}
public bool LookupFoundry (string foundryName)
abstract class Foundry
{
- public abstract Type GetType (string componentName);
+ bool _fromConfig;
+
+ public bool FromConfig {
+ get { return _fromConfig; }
+ set { _fromConfig = value; }
+ }
+
+ public abstract Type GetType (string componentName, out string source, out string ns);
}
{
string tagName;
Type type;
-
-#if NET_2_0
string source;
+ public bool FromWebConfig {
+ get { return source != null; }
+ }
+
public TagNameFoundry (string tagName, string source)
{
this.tagName = tagName;
this.source = source;
}
-#endif
public TagNameFoundry (string tagName, Type type)
{
this.type = type;
}
- public override Type GetType (string componentName)
+ public override Type GetType (string componentName, out string source, out string ns)
{
- if (0 != String.Compare (componentName, tagName, true))
+ source = null;
+ ns = null;
+ if (0 != String.Compare (componentName, tagName, true, Helpers.InvariantCulture))
return null;
+ source = this.source;
return LoadType ();
}
Type LoadType ()
{
-#if NET_2_0
if (type != null)
return type;
return type;
ArrayList other_deps = new ArrayList ();
- type = UserControlParser.GetCompiledType (vpath, realpath, other_deps, context);
+ type = BuildManager.GetCompiledType (vpath);
if (type != null) {
AspGenerator.AddTypeToCache (other_deps, realpath, type);
- WebConfigurationManager.ExtraAssemblies.Add (type.Assembly.Location);
+ BuildManager.AddToReferencedAssemblies (type.Assembly);
}
return type;
-#else
- return type;
-#endif
}
public string TagName {
{
string nameSpace;
Assembly assembly;
-
+ string assemblyName;
+ Dictionary <string, Assembly> assemblyCache;
+
public AssemblyFoundry (Assembly assembly, string nameSpace)
{
this.assembly = assembly;
this.nameSpace = nameSpace;
+
+ if (assembly != null)
+ this.assemblyName = assembly.FullName;
+ else
+ this.assemblyName = null;
}
- public override Type GetType (string componentName)
+ public AssemblyFoundry (string assemblyName, string nameSpace)
+ {
+ this.assembly = null;
+ this.nameSpace = nameSpace;
+ this.assemblyName = assemblyName;
+ }
+
+ public override Type GetType (string componentName, out string source, out string ns)
{
- return assembly.GetType (nameSpace + "." + componentName, true, true);
+ source = null;
+ ns = nameSpace;
+
+ if (assembly == null && assemblyName != null)
+ assembly = GetAssemblyByName (assemblyName, true);
+
+ string typeName = String.Concat (nameSpace, ".", componentName);
+ if (assembly != null)
+ return assembly.GetType (typeName, false, true);
+
+ IList tla = BuildManager.TopLevelAssemblies;
+ if (tla != null && tla.Count > 0) {
+ Type ret = null;
+ foreach (Assembly asm in tla) {
+ if (asm == null)
+ continue;
+ ret = asm.GetType (typeName, false, true);
+ if (ret != null)
+ return ret;
+ }
+ }
+
+ return null;
+ }
+
+ Assembly GetAssemblyByName (string name, bool throwOnMissing)
+ {
+ if (assemblyCache == null)
+ assemblyCache = new Dictionary <string, Assembly> ();
+
+ if (assemblyCache.ContainsKey (name))
+ return assemblyCache [name];
+
+ Assembly assembly = null;
+ Exception error = null;
+ if (name.IndexOf (',') != -1) {
+ try {
+ assembly = Assembly.Load (name);
+ } catch (Exception e) { error = e; }
+ }
+
+ if (assembly == null) {
+ try {
+ assembly = Assembly.LoadWithPartialName (name);
+ } catch (Exception e) { error = e; }
+ }
+
+ if (assembly == null)
+ if (throwOnMissing)
+ throw new HttpException ("Assembly " + name + " not found", error);
+ else
+ return null;
+
+ assemblyCache.Add (name, assembly);
+ return assembly;
}
}
public CompoundFoundry (string tagPrefix)
{
this.tagPrefix = tagPrefix;
-#if NET_2_0
tagnames = new Hashtable (StringComparer.InvariantCultureIgnoreCase);
-#else
- tagnames = new Hashtable (CaseInsensitiveHashCodeProvider.DefaultInvariant,
- CaseInsensitiveComparer.DefaultInvariant);
-#endif
}
public void Add (Foundry foundry)
TagNameFoundry tn = (TagNameFoundry) foundry;
string tagName = tn.TagName;
if (tagnames.Contains (tagName)) {
+ if (tn.FromWebConfig)
+ return;
+
string msg = String.Format ("{0}:{1} already registered.", tagPrefix, tagName);
throw new ApplicationException (msg);
}
tagnames.Add (tagName, foundry);
}
- public override Type GetType (string componentName)
+ public override Type GetType (string componentName, out string source, out string ns)
{
+ source = null;
+ ns = null;
Type type = null;
Foundry foundry = tagnames [componentName] as Foundry;
if (foundry != null)
- return foundry.GetType (componentName);
+ return foundry.GetType (componentName, out source, out ns);
if (assemblyFoundry != null) {
try {
- type = assemblyFoundry.GetType (componentName);
+ type = assemblyFoundry.GetType (componentName, out source, out ns);
return type;
} catch { }
}
- string msg = String.Format ("Type {0} not registered for prefix {1}",
- componentName, tagPrefix);
+ string msg = String.Format ("Type {0} not registered for prefix {1}", componentName, tagPrefix);
throw new ApplicationException (msg);
}
}
}
}
-