Commit bef7af6b authored by Marc Gravell's avatar Marc Gravell

Avoid type-name conflicts causing cache conflicts (makes the cache per-T; also...

Avoid type-name conflicts causing cache conflicts (makes the cache per-T; also avoids locking on the happy-path)
parent c03040da
...@@ -4466,15 +4466,12 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express ...@@ -4466,15 +4466,12 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express
var dynamicParamName = string.Join(string.Empty, names.ToArray()); var dynamicParamName = string.Join(string.Empty, names.ToArray());
// Before we get all emitty... // Before we get all emitty...
var lookup = typeof(T).Name + "_" + string.Join("|", names.ToArray()); var lookup = string.Join("|", names.ToArray());
Action<object, DynamicParameters> setter = null;
lock (cachedOutputSettersLock) var cache = CachedOutputSetters<T>.Cache;
{ var setter = (Action<object, DynamicParameters>)cache[lookup];
if (cachedOutputSetters.TryGetValue(lookup, out setter))
{ if (setter != null) goto MAKECALLBACK;
goto MAKECALLBACK;
}
}
// Come on let's build a method, let's build it, let's build it now! // Come on let's build a method, let's build it, let's build it now!
var dm = new DynamicMethod(string.Format("ExpressionParam{0}", Guid.NewGuid()), null, new[] { typeof(object), this.GetType() }, true); var dm = new DynamicMethod(string.Format("ExpressionParam{0}", Guid.NewGuid()), null, new[] { typeof(object), this.GetType() }, true);
...@@ -4521,12 +4518,9 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express ...@@ -4521,12 +4518,9 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express
il.Emit(OpCodes.Ret); // GO il.Emit(OpCodes.Ret); // GO
setter = (Action<object, DynamicParameters>)dm.CreateDelegate(typeof(Action<object, DynamicParameters>)); setter = (Action<object, DynamicParameters>)dm.CreateDelegate(typeof(Action<object, DynamicParameters>));
lock (cachedOutputSettersLock) lock (cache)
{
if (!cachedOutputSetters.ContainsKey(lookup))
{ {
cachedOutputSetters.Add(lookup, setter); cache[lookup] = setter;
}
} }
// Queue the preparation to be fired off when adding parameters to the DbCommand // Queue the preparation to be fired off when adding parameters to the DbCommand
...@@ -4569,7 +4563,10 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express ...@@ -4569,7 +4563,10 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express
private readonly Dictionary<string, Action<object, DynamicParameters>> cachedOutputSetters = new Dictionary<string,Action<object,DynamicParameters>>(); private readonly Dictionary<string, Action<object, DynamicParameters>> cachedOutputSetters = new Dictionary<string,Action<object,DynamicParameters>>();
private readonly object cachedOutputSettersLock = new object(); internal static class CachedOutputSetters<T>
{
public static readonly Hashtable Cache = new Hashtable();
}
internal void FireOutputCallbacks() internal void FireOutputCallbacks()
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment