diff --git a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/InheritanceBasedAopConfigurer.cs b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/InheritanceBasedAopConfigurer.cs index b4f6fec9..4ff3430c 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/InheritanceBasedAopConfigurer.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/InheritanceBasedAopConfigurer.cs @@ -254,7 +254,6 @@ namespace Spring.Aop.Framework.AutoProxy { ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.ProxyTargetAttributes = this.ProxyTargetAttributes; - proxyFactory.ProxyTargetAttributes = this.ProxyDeclaredMembersOnly; proxyFactory.TargetSource = new InheritanceBasedAopTargetSource(objectType); if (!ProxyInterfaces) { diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/CachedAopProxyFactory.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/CachedAopProxyFactory.cs index a7dddc50..19f67da7 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/CachedAopProxyFactory.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/CachedAopProxyFactory.cs @@ -1,205 +1,213 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#endregion - -#region Imports - -using System; -using System.Text; -using System.Collections; - -using Common.Logging; -using Spring.Proxy; - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// Implementation of the - /// interface that caches the AOP proxy instance. - /// - /// - ///

- /// Caches against a key based on : - /// - the base type - /// - the target type - /// - the interfaces to proxy - ///

- ///
- /// Bruno Baia - /// Erich Eichinger - /// - /// - [Serializable] - public class CachedAopProxyFactory : DefaultAopProxyFactory - { - /// - /// The shared instance for this class. - /// - private static readonly ILog logger = LogManager.GetLogger(typeof(CachedAopProxyFactory)); - - private static readonly Hashtable typeCache = new Hashtable(); - +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +#region Imports + +using System; +using System.Text; +using System.Collections; + +using Common.Logging; +using Spring.Proxy; + +#endregion + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// Implementation of the + /// interface that caches the AOP proxy instance. + /// + /// + ///

+ /// Caches against a key based on : + /// - the base type + /// - the target type + /// - the interfaces to proxy + ///

+ ///
+ /// Bruno Baia + /// Erich Eichinger + /// + /// + [Serializable] + public class CachedAopProxyFactory : DefaultAopProxyFactory + { + /// + /// The shared instance for this class. + /// + private static readonly ILog logger = LogManager.GetLogger(typeof(CachedAopProxyFactory)); + + private static readonly Hashtable typeCache = new Hashtable(); + /// /// Returns the number of proxy types in the cache - /// - public static int CountCachedTypes + /// + public static int CountCachedTypes { get { return typeCache.Count; } - } - + } + /// /// Clears the type cache - /// - public static void ClearCache() + /// + public static void ClearCache() { typeCache.Clear(); - } - + } + /// /// Creates a new instance - /// - public CachedAopProxyFactory() + /// + public CachedAopProxyFactory() {} - /// - /// Generates the proxy type and caches the - /// instance against the base type and the interfaces to proxy. - /// - /// - /// The to use - /// - /// The generated or cached proxy class. - protected override Type BuildProxyType(IProxyTypeBuilder typeBuilder) - { - ProxyTypeCacheKey cacheKey = new ProxyTypeCacheKey( - typeBuilder.BaseType, typeBuilder.TargetType, typeBuilder.Interfaces); - Type proxyType = null; - lock (typeCache) - { - proxyType = typeCache[cacheKey] as Type; - if (proxyType == null) - { - proxyType = typeBuilder.BuildProxyType(); - typeCache[cacheKey] = proxyType; - } - else - { - #region Instrumentation - - if (logger.IsInfoEnabled) - { - logger.Info(String.Format( - "AOP proxy type found in cache for '{0}'.", cacheKey)); - } - - #endregion - } - } - return proxyType; - } - - #region ProxyTypeCacheKey inner class implementation - - /// - /// Uniquely identifies a proxytype in the cache - /// - private sealed class ProxyTypeCacheKey - { - private sealed class HashCodeComparer : IComparer - { - public int Compare(object x, object y) - { - return x.GetHashCode().CompareTo(y.GetHashCode()); - } - } - - private static IComparer interfaceComparer = new HashCodeComparer(); - - private Type baseType; - private Type targetType; - private Type[] interfaceTypes; - - public ProxyTypeCacheKey(Type baseType, Type targetType, Type[] interfaceTypes) - { - this.baseType = baseType; - this.targetType = targetType; - Array.Sort(interfaceTypes, interfaceComparer); // sort by GetHashcode()? to have a defined order - this.interfaceTypes = interfaceTypes; - } - - public override bool Equals(object obj) - { - if (this == obj) - { - return true; - } - ProxyTypeCacheKey proxyTypeCacheKey = obj as ProxyTypeCacheKey; - if (proxyTypeCacheKey == null) - { - return false; - } - if (!Equals(targetType, proxyTypeCacheKey.targetType)) - { - return false; - } - if (!Equals(baseType, proxyTypeCacheKey.baseType)) - { - return false; - } - for (int i = 0; i < interfaceTypes.Length; i++) - { - if (!Equals(interfaceTypes[i], proxyTypeCacheKey.interfaceTypes[i])) - { - return false; - } - } - return true; - } - - public override int GetHashCode() - { - int result = baseType.GetHashCode(); - result = 29*result + targetType.GetHashCode(); - for (int i = 0; i < interfaceTypes.Length; i++) - { - result = 29 * result + interfaceTypes[i].GetHashCode(); - } - return result; - } - - public override string ToString() - { - StringBuilder buffer = new StringBuilder(); - buffer.Append("baseType=" + baseType + "; "); - buffer.Append("targetType=" + targetType + "; "); - buffer.Append("interfaceTypes=["); - foreach (Type intf in interfaceTypes) - { - buffer.Append(intf + ";"); - } - buffer.Append("]; "); - return buffer.ToString(); - } - } - - #endregion - } + /// + /// Generates the proxy type and caches the + /// instance against the base type and the interfaces to proxy. + /// + /// + /// The to use + /// + /// The generated or cached proxy class. + protected override Type BuildProxyType(IProxyTypeBuilder typeBuilder) + { + ProxyTypeCacheKey cacheKey = new ProxyTypeCacheKey( + typeBuilder.BaseType, typeBuilder.TargetType, typeBuilder.Interfaces, typeBuilder.ProxyTargetAttributes); + Type proxyType = null; + lock (typeCache) + { + proxyType = typeCache[cacheKey] as Type; + if (proxyType == null) + { + proxyType = typeBuilder.BuildProxyType(); + typeCache[cacheKey] = proxyType; + } + else + { + #region Instrumentation + + if (logger.IsInfoEnabled) + { + logger.Info(String.Format( + "AOP proxy type found in cache for '{0}'.", cacheKey)); + } + + #endregion + } + } + return proxyType; + } + + #region ProxyTypeCacheKey inner class implementation + + /// + /// Uniquely identifies a proxytype in the cache + /// + private sealed class ProxyTypeCacheKey + { + private sealed class HashCodeComparer : IComparer + { + public int Compare(object x, object y) + { + return x.GetHashCode().CompareTo(y.GetHashCode()); + } + } + + private static IComparer interfaceComparer = new HashCodeComparer(); + + private Type baseType; + private Type targetType; + private Type[] interfaceTypes; + private bool proxyTargetAttributes; + + public ProxyTypeCacheKey(Type baseType, Type targetType, Type[] interfaceTypes, bool proxyTargetAttributes) + { + this.baseType = baseType; + this.targetType = targetType; + Array.Sort(interfaceTypes, interfaceComparer); // sort by GetHashcode()? to have a defined order + this.interfaceTypes = interfaceTypes; + this.proxyTargetAttributes = proxyTargetAttributes; + } + + public override bool Equals(object obj) + { + if (this == obj) + { + return true; + } + ProxyTypeCacheKey proxyTypeCacheKey = obj as ProxyTypeCacheKey; + if (proxyTypeCacheKey == null) + { + return false; + } + if (!Equals(targetType, proxyTypeCacheKey.targetType)) + { + return false; + } + if (!Equals(baseType, proxyTypeCacheKey.baseType)) + { + return false; + } + for (int i = 0; i < interfaceTypes.Length; i++) + { + if (!Equals(interfaceTypes[i], proxyTypeCacheKey.interfaceTypes[i])) + { + return false; + } + } + if (proxyTargetAttributes != proxyTypeCacheKey.proxyTargetAttributes) + { + return false; + } + return true; + } + + public override int GetHashCode() + { + int result = baseType.GetHashCode(); + result = 29*result + targetType.GetHashCode(); + for (int i = 0; i < interfaceTypes.Length; i++) + { + result = 29 * result + interfaceTypes[i].GetHashCode(); + } + result = 29 * result + proxyTargetAttributes.GetHashCode(); + return result; + } + + public override string ToString() + { + StringBuilder buffer = new StringBuilder(); + buffer.Append("baseType=" + baseType + "; "); + buffer.Append("targetType=" + targetType + "; "); + buffer.Append("interfaceTypes=["); + foreach (Type intf in interfaceTypes) + { + buffer.Append(intf + ";"); + } + buffer.Append("]; "); + buffer.Append("proxyTargetAttributes=" + proxyTargetAttributes + "; "); + return buffer.ToString(); + } + } + + #endregion + } } \ No newline at end of file diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/CachedAopProxyFactoryTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/CachedAopProxyFactoryTests.cs index 10e5eae3..06c0ead1 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/CachedAopProxyFactoryTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/CachedAopProxyFactoryTests.cs @@ -80,6 +80,20 @@ namespace Spring.Aop.Framework.DynamicProxy AssertAopProxyTypeCacheCount(2); } + [Test] + public void DoesNotCacheWithDifferentProxyTargetAttributes() + { + ProxyFactory advisedSupport = new ProxyFactory(new GoodCommand()); + advisedSupport.ProxyTargetAttributes = true; + CreateAopProxy(advisedSupport); + + advisedSupport = new ProxyFactory(new GoodCommand()); + advisedSupport.ProxyTargetAttributes = false; + CreateAopProxy(advisedSupport); + + AssertAopProxyTypeCacheCount(2); + } + [Test] public void DoesNotCacheWithDifferentInterfaces() {