Permalink
Browse files

Add caching to AssemblyUtils.FindType and change all slower Type.GetT…

…ype calls to use that
  • Loading branch information...
1 parent 41f57ed commit c8f80e8467d5f2c694e8e334db13b67618f25fb1 @mythz mythz committed Dec 7, 2012
@@ -1,11 +1,13 @@
using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
#if SILVERLIGHT
#endif
+using System.Threading;
using ServiceStack.Common.Support;
namespace ServiceStack.Text
@@ -20,6 +22,8 @@ public static class AssemblyUtils
private const string ExeExt = "dll";
private const char UriSeperator = '/';
+ private static Dictionary<string, Type> TypeCache = new Dictionary<string, Type>();
+
#if !XBOX
/// <summary>
/// Find the type from the name supplied
@@ -28,19 +32,31 @@ public static class AssemblyUtils
/// <returns></returns>
public static Type FindType(string typeName)
{
+ Type type = null;
+ if (TypeCache.TryGetValue(typeName, out type)) return type;
+
#if !SILVERLIGHT
- var type = Type.GetType(typeName);
- if (type != null) return type;
+ type = Type.GetType(typeName);
#endif
- var typeDef = new AssemblyTypeDefinition(typeName);
- if (!String.IsNullOrEmpty(typeDef.AssemblyName))
+ if (type == null)
{
- return FindType(typeDef.TypeName, typeDef.AssemblyName);
+ var typeDef = new AssemblyTypeDefinition(typeName);
+ type = !string.IsNullOrEmpty(typeDef.AssemblyName)
+ ? FindType(typeDef.TypeName, typeDef.AssemblyName)
+ : FindTypeFromLoadedAssemblies(typeDef.TypeName);
}
- else
+
+ Dictionary<string, Type> snapshot, newCache;
+ do
{
- return FindTypeFromLoadedAssemblies(typeDef.TypeName);
- }
+ snapshot = TypeCache;
+ newCache = new Dictionary<string, Type>(TypeCache);
+ newCache[typeName] = type;
+
+ } while (!ReferenceEquals(
+ Interlocked.CompareExchange(ref TypeCache, newCache, snapshot), snapshot));
+
+ return type;
}
#endif
@@ -87,7 +87,7 @@ internal static class DeserializeTypeRefJson
if (instance == null && possibleTypeInfo && propertyName == JsWriter.TypeAttr)
{
var explicitTypeName = Serializer.ParseString(propertyValueStr);
- var explicitType = Type.GetType(explicitTypeName);
+ var explicitType = AssemblyUtils.FindType(explicitTypeName);
if (explicitType != null && !explicitType.IsInterface && !explicitType.IsAbstract) {
instance = explicitType.CreateInstance();
}
@@ -43,7 +43,7 @@ internal static class DeserializeTypeRefJsv
if (possibleTypeInfo && propertyName == JsWriter.TypeAttr)
{
var explicitTypeName = Serializer.ParseString(propertyValueStr);
- var explicitType = Type.GetType(explicitTypeName);
+ var explicitType = AssemblyUtils.FindType(explicitTypeName);
if (explicitType != null && !explicitType.IsInterface && !explicitType.IsAbstract) {
instance = explicitType.CreateInstance();
}
@@ -53,7 +53,7 @@ public static ParseStringDelegate GetSpecialParseMethod(Type type)
public static Type ParseType(string assemblyQualifiedName)
{
- return Type.GetType(assemblyQualifiedName.FromCsvField());
+ return AssemblyUtils.FindType(assemblyQualifiedName.FromCsvField());
}
}
@@ -10,9 +10,9 @@ static Env()
var platform = (int)Environment.OSVersion.Platform;
IsUnix = (platform == 4) || (platform == 6) || (platform == 128);
- IsMono = Type.GetType("Mono.Runtime") != null;
+ IsMono = AssemblyUtils.FindType("Mono.Runtime") != null;
- IsMonoTouch = Type.GetType("MonoTouch.Foundation.NSObject") != null;
+ IsMonoTouch = AssemblyUtils.FindType("MonoTouch.Foundation.NSObject") != null;
SupportsExpressions = SupportsEmit = !IsMonoTouch;
@@ -57,7 +57,7 @@ public Type SomeType
return idx < 0 ? null :
(
this[idx].Value is string
- ? Type.GetType(((string)this[idx].Value).FromCsvField())
+ ? AssemblyUtils.FindType(((string)this[idx].Value).FromCsvField())
: this[idx].Value as Type
);
}
@@ -178,7 +178,7 @@ public void Can_deserialise_polymorphic_list_serialized_by_datacontractjsonseria
var regex = new Regex(@"^(?<type>[^:]+):#(?<namespace>.*)$");
var match = regex.Match(value);
var typeName = string.Format("{0}.{1}", match.Groups["namespace"].Value, match.Groups["type"].Value.Replace(".", "+"));
- return Type.GetType(typeName);
+ return AssemblyUtils.FindType(typeName);
};
try {
@@ -272,7 +272,7 @@ public void Can_deserialise_an_entity_containing_a_polymorphic_property_serializ
var regex = new Regex(@"^(?<type>[^:]+):#(?<namespace>.*)$");
var match = regex.Match(value);
var typeName = string.Format("{0}.{1}", match.Groups["namespace"].Value, match.Groups["type"].Value.Replace(".", "+"));
- return Type.GetType(typeName);
+ return AssemblyUtils.FindType(typeName);
};
try {

0 comments on commit c8f80e8

Please sign in to comment.