User: xtoff
Date: 2010/02/20 05:07 AM

Added:
 /DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/
  ProxyTypeCachingTestCase.cs

Modified:
 /DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/
  Castle.DynamicProxy.Tests-vs2008.csproj
 /DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/BugsReported/
  DynProxy88.cs
 /DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/
  ClassProxyGenerator.cs, InterfaceProxyWithTargetGenerator.cs
 /DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/Emitters/
  TypeUtil.cs

Log:
 - implemented DYNPROXY-ISSUE-131 - Caching issue with order of interfaces.

File Changes:

Directory: /DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/BugsReported/
==========================================================================

File [modified]: DynProxy88.cs
Delta lines: +4 -0
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/Castle.DynamicProxy.Tests-vs2008.csproj
    2010-02-19 19:08:40 UTC (rev 6747)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/Castle.DynamicProxy.Tests-vs2008.csproj
    2010-02-20 12:07:56 UTC (rev 6748)
@@ -170,6 +170,7 @@
     <Compile Include="InterceptorSelectorTestCase.cs" />
     <Compile Include="InterfaceProxyBaseTypeTestCase.cs" />
     <Compile Include="InterfaceProxyWithTargetInterfaceTestCase.cs" />
+    <Compile Include="Interfaces\IBase.cs" />
     <Compile Include="Interfaces\IDecimalOutParam.cs" />
     <Compile Include="Interfaces\IdenticalInterfaces.cs" />
     <Compile Include="Interfaces\IEmpty.cs" />
@@ -178,6 +179,8 @@
     <Compile Include="Interfaces\IGenericWithRefOut.cs" />
     <Compile Include="Interfaces\INullable.cs" />
     <Compile Include="Interfaces\IOne.cs" />
+    <Compile Include="Interfaces\ISub1.cs" />
+    <Compile Include="Interfaces\ISub2.cs" />
     <Compile Include="Interfaces\ITwo.cs" />
     <Compile Include="Interfaces\IWithRefOut.cs" />
     <Compile Include="Interfaces\One.cs" />
@@ -232,6 +235,7 @@
     <Compile Include="ProxyKind.cs" />
     <Compile Include="ProxyNothingHook.cs" />
     <Compile Include="ProxyTargetAccessorHandlingTestCase.cs" />
+    <Compile Include="ProxyTypeCachingTestCase.cs" />
     <Compile Include="RhinoMocksTestCase.cs" />
     <Compile Include="SerializableClassTestCase.cs" />

Directory: /DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/
=============================================================

File [modified]: Castle.DynamicProxy.Tests-vs2008.csproj
Delta lines: +85 -0
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/ProxyTypeCachingTestCase.cs    
                            (rev 0)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/ProxyTypeCachingTestCase.cs    
    2010-02-20 12:07:56 UTC (rev 6748)
@@ -0,0 +1,85 @@
+// Copyright 2004-2010 Castle Project - http://www.castleproject.org/
+// 
+// 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.
+
+namespace Castle.DynamicProxy.Tests
+{
+       using System;
+       using System.Collections.Generic;
+
+       using Castle.DynamicProxy.Tests.Interfaces;
+
+       using NUnit.Framework;
+
+       [TestFixture]
+       public class ProxyTypeCachingTestCase : BasePEVerifyTestCase
+       {
+               private const string AllKinds = "All";
+
+               private object Proxy(ProxyKind kind, params Type[] 
additionalInterfacesToProxy)
+               {
+                       switch (kind)
+                       {
+                               case ProxyKind.Class:
+                                       return 
generator.CreateClassProxy(typeof(SimpleClass), additionalInterfacesToProxy);
+                               case ProxyKind.WithoutTarget:
+                                       return 
generator.CreateInterfaceProxyWithoutTarget(typeof(IEmpty), 
additionalInterfacesToProxy);
+                               case ProxyKind.WithTarget:
+                                       return 
generator.CreateInterfaceProxyWithTarget(typeof(IEmpty), 
additionalInterfacesToProxy, new Empty());
+                               case ProxyKind.WithTargetInterface:
+                                       return 
generator.CreateInterfaceProxyWithTarget(typeof(IEmpty), 
additionalInterfacesToProxy, new Empty());
+                               default:
+                                       Assert.Fail(string.Format("Invalid 
proxy kind: {0}", kind));
+                                       return null; //to satisfy the compiler
+                       }
+               }
+
+               public static IEnumerable<ProxyKind> All
+               {
+                       get
+                       {
+                               return new[]
+                               {
+                                       ProxyKind.Class,
+                                       ProxyKind.WithoutTarget,
+                                       ProxyKind.WithTarget,
+                                       ProxyKind.WithTargetInterface
+                               };
+                       }
+               }
+
+               [Test]
+               public void 
Duplicated_interfaces_not_significant([ValueSource(AllKinds)] ProxyKind kind)
+               {
+                       var first = Proxy(kind, typeof(IOne), typeof(IOne));
+                       var second = Proxy(kind, typeof(IOne));
+                       Assert.AreSame(first.GetType(), second.GetType());
+               }
+
+               [Test]
+               public void 
Explicit_inclusion_of_base_interfaces_not_significant([ValueSource(AllKinds)] 
ProxyKind kind)
+               {
+                       var first = Proxy(kind, typeof(IBase), typeof(ISub1));
+                       var second = Proxy(kind, typeof(ISub1));
+                       Assert.AreSame(first.GetType(), second.GetType());
+               }
+
+               [Test]
+               public void 
Order_of_additional_interfaces_not_significant([ValueSource(AllKinds)] 
ProxyKind kind)
+               {
+                       var first = Proxy(kind, typeof(IOne), typeof(ITwo));
+                       var second = Proxy(kind, typeof(ITwo), typeof(IOne));
+                       Assert.AreSame(first.GetType(), second.GetType());
+               }
+       }
+}

File [added]: ProxyTypeCachingTestCase.cs
Delta lines: +0 -0
===================================================================

Directory: /DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/Emitters/
===========================================================================

File [modified]: TypeUtil.cs
Delta lines: +5 -4
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/InterfaceProxyWithTargetGenerator.cs
  2010-02-19 19:08:40 UTC (rev 6747)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/InterfaceProxyWithTargetGenerator.cs
  2010-02-20 12:07:56 UTC (rev 6748)
@@ -1,4 +1,4 @@
-// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+// Copyright 2004-2010 Castle Project - http://www.castleproject.org/
 // 
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -51,6 +51,7 @@
                        EnsureValidBaseType(options.BaseTypeForInterfaceProxy);
                        Type proxyType;
 
+                       interfaces = TypeUtil.GetAllInterfaces(interfaces);
                        CacheKey cacheKey = new CacheKey(proxyTargetType, 
targetType, interfaces, options);
 
                        using (var locker = Scope.Lock.ForReadingUpgradeable())
@@ -228,8 +229,8 @@
                        var mixins = new MixinContributor(namingScope, 
AllowChangeTarget) { Logger = Logger };
                        // Order of interface precedence:
                        // 1. first target
-                       var targetInterfaces = 
TypeUtil.GetAllInterfaces(proxyTargetType);
-                       var additionalInterfaces = 
TypeUtil.GetAllInterfaces(interfaces);
+                       ICollection<Type> targetInterfaces = 
TypeUtil.GetAllInterfaces(proxyTargetType);
+                       ICollection<Type> additionalInterfaces = 
TypeUtil.GetAllInterfaces(interfaces);
                        var target = 
AddMappingForTargetType(typeImplementerMapping, proxyTargetType, 
targetInterfaces, additionalInterfaces,namingScope);
 
                        // 2. then mixins
@@ -301,7 +302,7 @@
                {
                        var contributor = new 
InterfaceProxyTargetContributor(proxyTargetType, AllowChangeTarget, namingScope)
                        { Logger = Logger };
-                       var proxiedInterfaces = 
TypeUtil.GetAllInterfaces(targetType);
+                       ICollection<Type> proxiedInterfaces = 
TypeUtil.GetAllInterfaces(targetType);
                        foreach (var @interface in proxiedInterfaces)
                        {

Directory: /DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/
==================================================================

File [modified]: ClassProxyGenerator.cs
Delta lines: +14 -7
===================================================================

--- DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/Emitters/TypeUtil.cs  
2010-02-19 19:08:40 UTC (rev 6747)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/Emitters/TypeUtil.cs  
2010-02-20 12:07:56 UTC (rev 6748)
@@ -16,6 +16,7 @@
 {
        using System;
        using System.Collections.Generic;
+       using System.Linq;
        using System.Reflection;
 
        public abstract class TypeUtil
@@ -25,16 +26,14 @@
                /// </summary>
                /// <param name="types"></param>
                /// <returns></returns>
-               public static ICollection<Type> GetAllInterfaces(params Type[] 
types)
+               public static Type[] GetAllInterfaces(params Type[] types)
                {
                        if (types == null)
                        {
                                return Type.EmptyTypes;
                        }
 
-                       var dummy = new object();
-                       // we should move this to HashSet once we no longer 
support .NET 2.0
-                       IDictionary<Type, object> interfaces = new 
Dictionary<Type, object>();
+                       var interfaces = new HashSet<Type>();
                        foreach (var type in types)
                        {
                                if (type == null)
@@ -44,17 +43,25 @@
 
                                if (type.IsInterface)
                                {
-                                       interfaces[type] = dummy;
+                                       interfaces.Add(type);
                                }
 
                                foreach (var @interface in type.GetInterfaces())
                                {
-                                       interfac...@interface] = dummy;
+                                       interfaces.Add(@interface);
                                }
                        }
-                       return interfaces.Keys;
+                       return Sort(interfaces);
                }
 
+               private static Type[] Sort(IEnumerable<Type> types)
+               {
+                       var array = types.ToArray();
+                       //NOTE: is there a better, stable way to sort Types. We 
will need to revise this once we allow open generics
+                       Array.Sort(array, (l, r) => 
string.Compare(l.AssemblyQualifiedName, r.AssemblyQualifiedName));
+                       return array;
+               }
+
                public static Type GetClosedParameterType(AbstractTypeEmitter 
type, Type parameter)
                {

File [modified]: InterfaceProxyWithTargetGenerator.cs
Delta lines: +5 -16
===================================================================

--- DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/BugsReported/DynProxy88.cs 
2010-02-19 19:08:40 UTC (rev 6747)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/BugsReported/DynProxy88.cs 
2010-02-20 12:07:56 UTC (rev 6748)
@@ -1,4 +1,4 @@
-// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+// Copyright 2004-2010 Castle Project - http://www.castleproject.org/
 // 
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -15,7 +15,10 @@
 namespace Castle.DynamicProxy.Tests.BugsReported
 {
        using System;
-       using Core.Interceptor;
+
+       using Castle.Core.Interceptor;
+       using Castle.DynamicProxy.Tests.Interfaces;
+
        using NUnit.Framework;
 
        [TestFixture]
@@ -34,11 +37,6 @@
                }
        }
 
-       public interface IBase
-       {
-               void Foo();
-       }
-
        public class Inherited : IBase
        {
                public void Foo()
@@ -47,15 +45,6 @@
                }
        }
 
-       public interface ISub1 : IBase
-       {
-               void Bar();
-       }
-       public interface ISub2 : IBase
-       {
-               void Baz();
-       }
-
        public class MyFoo:Inherited,ISub1,ISub2
        {

-- 
You received this message because you are subscribed to the Google Groups 
"Castle Project Commits" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/castle-project-commits?hl=en.

Reply via email to