Skip to content

Commit

Permalink
Improve performance for mocking interfaces: Cache GetInterfaceMap
Browse files Browse the repository at this point in the history
Fixes #1350.
  • Loading branch information
Andre authored and rauhs committed Aug 8, 2023
1 parent 0097c35 commit eb8ccf9
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/Moq/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt.

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
Expand Down Expand Up @@ -155,7 +156,7 @@ public static MethodInfo GetImplementingMethod(this MethodInfo method, Type prox
{
Debug.Assert(declaringType.IsAssignableFrom(proxyType));

var map = proxyType.GetInterfaceMap(method.DeclaringType);
var map = GetInterfaceMap(proxyType, method.DeclaringType);
var index = Array.IndexOf(map.InterfaceMethods, method);
Debug.Assert(index >= 0);
return map.TargetMethods[index].GetBaseDefinition();
Expand Down Expand Up @@ -518,6 +519,13 @@ public static Type SubstituteTypeMatchers(this Type type, Type other)
return type;
}

private static readonly ConcurrentDictionary<Tuple<Type, Type>, InterfaceMapping> mappingsCache = new ();

private static InterfaceMapping GetInterfaceMap(Type type, Type interfaceType)
{
return mappingsCache.GetOrAdd(Tuple.Create(type, interfaceType), tuple => tuple.Item1.GetInterfaceMap(tuple.Item2));
}

public static IEnumerable<Mock> FindAllInnerMocks(this SetupCollection setups)
{
return setups.FindAll(setup => !setup.IsConditional)
Expand Down

0 comments on commit eb8ccf9

Please sign in to comment.