Permalink
Browse files

use linq expression for object creation

  • Loading branch information...
1 parent dc76189 commit 0f19da5044c38eca5138842d14252cf7ac0ae0f2 @testn testn committed Oct 26, 2010
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
+using MongoDB.Configuration.Mapping.Util;
namespace MongoDB.Configuration.Mapping.Model
{
@@ -12,6 +13,7 @@ public abstract class ClassMapBase : IClassMap
{
private readonly List<PersistentMemberMap> _memberMaps;
private readonly List<SubClassMap> _subClassMaps;
+ private Func<object> _creator;
private readonly bool _hasProtectedOrPublicConstructor;
/// <summary>
@@ -136,6 +138,12 @@ public IEnumerable<SubClassMap> SubClassMaps
get { return _subClassMaps.AsReadOnly(); }
}
+ private void EnsureCreator()
+ {
+ if (_creator == null)
+ _creator = MemberReflectionOptimizer.GetCreator(ClassType);
+ }
+
/// <summary>
/// Creates an instance of the entity.
/// </summary>
@@ -148,10 +156,12 @@ public virtual object CreateInstance()
if (ClassType.IsAbstract)
throw new MongoException("Unable to create an instance of an abstract class.");
+ EnsureCreator();
+
//TODO: figure out how to support custom activators...
- var instance = Activator.CreateInstance(ClassType, true);
+ object instance = _creator.Invoke();
- //initialize all default values in case something isn't specified when reader the document.
+ //initialize all default values in case something isn't specified when reader the document.)
foreach(var memberMap in MemberMaps.Where(x => x.DefaultValue != null))
memberMap.SetValue(instance, memberMap.DefaultValue);
@@ -13,6 +13,7 @@ public static class MemberReflectionOptimizer
{
private static readonly Dictionary<string, Func<object, object>> GetterCache = new Dictionary<string, Func<object, object>>();
private static readonly Dictionary<string, Action<object, object>> SetterCache = new Dictionary<string, Action<object, object>>();
+ private static readonly Dictionary<RuntimeTypeHandle, Func<object>> CreatorCache = new Dictionary<RuntimeTypeHandle, Func<object>>();
private static readonly object SyncObject = new object();
/// <summary>
@@ -225,6 +226,31 @@ public static class MemberReflectionOptimizer
}
/// <summary>
+ /// Gets an instance creator
+ /// </summary>
+ /// <param name="type">Type to instantiate</param>
+ /// <returns>A delegate to create an object of the given type</returns>
+ public static Func<object> GetCreator(Type type)
+ {
+ Func<object> creator;
+ RuntimeTypeHandle runtimeTypeHandle = type.TypeHandle;
+ lock (SyncObject)
+ {
+ if (CreatorCache.TryGetValue(runtimeTypeHandle, out creator))
+ return creator;
+ }
+ ConstructorInfo defaultConstructor = type.GetConstructor(BindingFlags.Instance |
+ BindingFlags.Public |
+ BindingFlags.NonPublic, null, new Type[0], new ParameterModifier[0]);
+ creator = Expression.Lambda<Func<object>>(Expression.New(defaultConstructor)).Compile();
+ lock (SyncObject)
+ {
+ CreatorCache[runtimeTypeHandle] = creator;
+ }
+ return creator;
+ }
+
+ /// <summary>
/// Creates the key.
/// </summary>
/// <param name = "memberInfo">The member info.</param>

0 comments on commit 0f19da5

Please sign in to comment.