Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace Castle.Components.DictionaryAdapter
{
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
Expand All @@ -34,8 +35,8 @@ namespace Castle.Components.DictionaryAdapter
/// </summary>
public class DictionaryAdapterFactory : IDictionaryAdapterFactory
{
private readonly SynchronizedDictionary<Type, DictionaryAdapterMeta> interfaceToMeta =
new SynchronizedDictionary<Type, DictionaryAdapterMeta>();
private readonly ConcurrentDictionary<Type, DictionaryAdapterMeta> interfaceToMeta =
new ConcurrentDictionary<Type, DictionaryAdapterMeta>();

#region IDictionaryAdapterFactory

Expand Down
120 changes: 0 additions & 120 deletions src/Castle.Core/Core/Internal/SynchronizedDictionary.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ private Type GetDelegateType(MetaMethod method, ClassEmitter @class)
GetCacheKeyTypes(method),
null);

return scope.TypeCache.GetOrAddWithoutTakingLock(key, _ =>
return scope.GetOrAddFromCache(key, _ =>
new DelegateTypeGenerator(method, targetType)
.Generate(@class, namingScope)
.BuildType());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ private Type GetDelegateType(MetaMethod method, ClassEmitter @class)
GetCacheKeyTypes(method),
null);

return scope.TypeCache.GetOrAddWithoutTakingLock(key, _ =>
return scope.GetOrAddFromCache(key, _ =>
new DelegateTypeGenerator(method, targetType)
.Generate(@class, namingScope)
.BuildType());
Expand All @@ -136,7 +136,7 @@ private Type GetInvocationType(MetaMethod method, ClassEmitter @class)

// no locking required as we're already within a lock

return scope.TypeCache.GetOrAddWithoutTakingLock(key, _ => BuildInvocationType(method, @class));
return scope.GetOrAddFromCache(key, _ => BuildInvocationType(method, @class));
}

private MethodGenerator IndirectlyCalledMethodGenerator(MetaMethod method, ClassEmitter proxy,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ private Type GetInvocationType(MetaMethod method, ClassEmitter @class)

// no locking required as we're already within a lock

return scope.TypeCache.GetOrAddWithoutTakingLock(key, _ =>
return scope.GetOrAddFromCache(key, _ =>
new CompositionInvocationTypeGenerator(method.Method.DeclaringType,
method,
method.Method,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ private Type GetInvocationType(MetaMethod method, ClassEmitter emitter)

// no locking required as we're already within a lock

return scope.TypeCache.GetOrAddWithoutTakingLock(key, _ =>
return scope.GetOrAddFromCache(key, _ =>
new CompositionInvocationTypeGenerator(methodInfo.DeclaringType,
method,
methodInfo,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ private Type GetInvocationType(MetaMethod method, ClassEmitter emitter)

// no locking required as we're already within a lock

return scope.TypeCache.GetOrAddWithoutTakingLock(key, _ =>
return scope.GetOrAddFromCache(key, _ =>
new CompositionInvocationTypeGenerator(method.Method.DeclaringType,
method,
method.Method,
Expand Down
2 changes: 1 addition & 1 deletion src/Castle.Core/DynamicProxy/DefaultProxyBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ private void AssertValidTypeForTarget(Type type, Type target, string paramName)
}
}

private void AssertValidTypes(IEnumerable<Type>? targetTypes, string paramName)
private void AssertValidTypes(Type[]? targetTypes, string paramName)
{
if (targetTypes != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,11 @@ private void EnsureValidBaseType(Type type)
"Base type for proxy is null reference. Please set it to System.Object or some other valid type.");
}

if (typeof(object).Equals(type))
{
return; // Skip GetConstructor reflection for System.Object
}

if (!type.IsClass)
{
ThrowInvalidBaseType(type, "it is not a class type");
Expand Down
6 changes: 4 additions & 2 deletions src/Castle.Core/DynamicProxy/Generators/BaseProxyGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ internal abstract class BaseProxyGenerator
protected readonly Type[] interfaces;
private readonly ModuleScope scope;
private ILogger logger = NullLogger.Instance;
private ProxyGenerationOptions proxyGenerationOptions;
private readonly ProxyGenerationOptions proxyGenerationOptions;

protected BaseProxyGenerator(ModuleScope scope, Type targetType, Type[] interfaces, ProxyGenerationOptions proxyGenerationOptions)
{
Expand Down Expand Up @@ -74,9 +74,11 @@ public Type GetProxyType()
{
bool notFoundInTypeCache = false;

var proxyType = Scope.TypeCache.GetOrAdd(GetCacheKey(), cacheKey =>
var cacheKey = GetCacheKey();
var proxyType = Scope.GetOrAddFromCache(cacheKey, key =>
{
notFoundInTypeCache = true;

Logger.DebugFormat("No cached proxy type was found for target type {0}.", targetType.FullName);

EnsureOptionsOverrideEqualsAndGetHashCode();
Expand Down
26 changes: 10 additions & 16 deletions src/Castle.Core/DynamicProxy/Generators/CacheKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace Castle.DynamicProxy.Generators
#if FEATURE_SERIALIZATION
[Serializable]
#endif
internal class CacheKey
internal struct CacheKey : IEquatable<CacheKey>
{
private readonly MemberInfo target;
private readonly Type[] interfaces;
Expand Down Expand Up @@ -73,37 +73,31 @@ public override int GetHashCode()

public override bool Equals(object obj)
{
if (this == obj)
{
return true;
}

var cacheKey = obj as CacheKey;
if (cacheKey == null)
{
return false;
}
return obj is CacheKey other && Equals(other);
}

if (!Equals(type, cacheKey.type))
public bool Equals(CacheKey other)
{
if (!Equals(type, other.type))
{
return false;
}
if (!Equals(target, cacheKey.target))
if (!Equals(target, other.target))
{
return false;
}
if (interfaces.Length != cacheKey.interfaces.Length)
if (interfaces.Length != other.interfaces.Length)
{
return false;
}
for (var i = 0; i < interfaces.Length; i++)
{
if (!Equals(interfaces[i], cacheKey.interfaces[i]))
if (!Equals(interfaces[i], other.interfaces[i]))
{
return false;
}
}
if (!Equals(options, cacheKey.options))
if (!Equals(options, other.options))
{
return false;
}
Expand Down
8 changes: 3 additions & 5 deletions src/Castle.Core/DynamicProxy/Internal/InvocationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,16 @@
namespace Castle.DynamicProxy.Internal
{
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Reflection;
using System.Threading;

using Castle.Core.Internal;
using Castle.DynamicProxy.Generators;

internal static class InvocationHelper
{
private static readonly SynchronizedDictionary<CacheKey, MethodInfo> cache =
new SynchronizedDictionary<CacheKey, MethodInfo>();
private static readonly ConcurrentDictionary<CacheKey, MethodInfo> cache =
new ConcurrentDictionary<CacheKey, MethodInfo>();

public static MethodInfo GetMethodOnObject(object target, MethodInfo proxiedMethod)
{
Expand Down
12 changes: 6 additions & 6 deletions src/Castle.Core/DynamicProxy/Internal/TypeUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,14 @@ internal static MethodInfo[] GetAllInstanceMethods(this Type type)
/// </summary>
internal static Type[] GetAllInterfaces(params Type[]? types)
{
if (types == null)
if (types == null || types.Length == 0)
{
return Type.EmptyTypes;
}

var interfaces = new HashSet<Type>();
for (var index = 0; index < types.Length; index++)
foreach (var type in types)
{
var type = types[index];
if (type == null)
{
continue;
Expand All @@ -153,9 +152,8 @@ internal static Type[] GetAllInterfaces(params Type[]? types)
}

var innerInterfaces = type.GetInterfaces();
for (var i = 0; i < innerInterfaces.Length; i++)
foreach (var @interface in innerInterfaces)
{
var @interface = innerInterfaces[i];
interfaces.Add(@interface);
}
}
Expand All @@ -168,7 +166,6 @@ public static Type[] GetAllInterfaces(this Type type) // NOTE: also used by Win
return GetAllInterfaces(new[] { type });
}


public static Type? GetTypeOrNull(object? target)
{
if (target == null)
Expand Down Expand Up @@ -307,6 +304,9 @@ internal static bool IsDelegateType(this Type type)

private static Type[] Sort(ICollection<Type> types)
{
if (types.Count == 0)
return Type.EmptyTypes;

var array = new Type[types.Count];
types.CopyTo(array, 0);
//NOTE: is there a better, stable way to sort Types. We will need to revise this once we allow open generics
Expand Down
Loading
Loading