From 179a2fd053b7db9b2e39b3dcab0052fe640d63b4 Mon Sep 17 00:00:00 2001 From: Darren Ronda Date: Thu, 13 Feb 2025 13:44:02 -0800 Subject: [PATCH] When get proxy of classes use seperate ProxyGenerator for each namespace for performance improvement --- src/Moq/Interception/CastleProxyFactory.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Moq/Interception/CastleProxyFactory.cs b/src/Moq/Interception/CastleProxyFactory.cs index 0a374e638..5bca46b2d 100644 --- a/src/Moq/Interception/CastleProxyFactory.cs +++ b/src/Moq/Interception/CastleProxyFactory.cs @@ -2,11 +2,11 @@ // All rights reserved. Licensed under the BSD 3-Clause License; see License.txt. using System; +using System.Collections.Concurrent; using System.Diagnostics; using System.Reflection; #if FEATURE_DEFAULT_INTERFACE_IMPLEMENTATIONS -using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; @@ -28,11 +28,19 @@ sealed class CastleProxyFactory : ProxyFactory { ProxyGenerationOptions generationOptions; ProxyGenerator generator; + ConcurrentDictionary classGenerators; public CastleProxyFactory() { this.generationOptions = new ProxyGenerationOptions { Hook = new IncludeObjectMethodsHook(), BaseTypeForInterfaceProxy = typeof(InterfaceProxy) }; this.generator = new ProxyGenerator(); + this.classGenerators = new ConcurrentDictionary(); + } + + ProxyGenerator GetClassGenerator(Type mockType) + { + var ns = mockType.Namespace ?? string.Empty; + return classGenerators.GetOrAdd(ns, _ => new ProxyGenerator()); } /// @@ -53,13 +61,13 @@ public override object CreateProxy(Type mockType, Moq.IInterceptor interceptor, { var options = new ProxyGenerationOptions(); options.AddDelegateTypeMixin(mockType); - var container = generator.CreateClassProxy(typeof(object), additionalInterfaces, options, new Interceptor(interceptor)); + var container = GetClassGenerator(mockType).CreateClassProxy(typeof(object), additionalInterfaces, options, new Interceptor(interceptor)); return Delegate.CreateDelegate(mockType, container, container.GetType().GetMethod("Invoke")); } try { - return generator.CreateClassProxy(mockType, additionalInterfaces, this.generationOptions, arguments, new Interceptor(interceptor)); + return GetClassGenerator(mockType).CreateClassProxy(mockType, additionalInterfaces, this.generationOptions, arguments, new Interceptor(interceptor)); } catch (TypeLoadException e) {