User: jonathon.rossi
Date: 2009/11/29 01:05 AM

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

Modified:
 /DynamicProxy/trunk/src/
  Changes.txt
 /DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/
  BasePEVerifyTestCase.cs, Castle.DynamicProxy.Tests-vs2008.csproj
 /DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/Classes/
  SimpleClass.cs
 /DynamicProxy/trunk/src/Castle.DynamicProxy/
  DefaultProxyBuilder.cs, IProxyBuilder.cs, ModuleScope.cs, 
ProxyGenerationOptions.cs, ProxyGenerator.cs
 /DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/
  ClassMembersCollector.cs, ClassProxyTargetContributor.cs, MembersCollector.cs
 /DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/
  AttributeDisassembler.cs, BaseProxyGenerator.cs, CacheKey.cs, 
ClassProxyGenerator.cs, InterfaceProxyWithTargetGenerator.cs, 
InvocationTypeGenerator.cs

Log:
 Fixed DYNPROXY-ISSUE-120: Add logging to DynamicProxy.
 Introduced basic logging for cache hit/miss, methods that cannot be 
intercepted, and overriding Equals/GetHashCode.

Directory Changes:

Directory: /DynamicProxy/trunk/src/
===================================

Property changes on: DynamicProxy/trunk/src
___________________________________________________________________
Directory: /svn:ignore/
=======================

   + *.suo
*.user


--- 
DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/ClassMembersCollector.cs
    2009-11-29 00:42:54 UTC (rev 6369)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/ClassMembersCollector.cs
    2009-11-29 08:05:35 UTC (rev 6370)
@@ -23,7 +23,6 @@
                public ClassMembersCollector(Type targetType, ITypeContributor 
targetContributor)
                        : base(targetType, targetContributor, true, new 
InterfaceMapping())
                {
-
                }
 
                protected override MethodToGenerate 
GetMethodToGenerate(MethodInfo method, IProxyGenerationHook hook, bool 
isStandalone)
@@ -48,6 +47,5 @@
 
                        return new MethodToGenerate(method, isStandalone, 
target, method, accepted);
                }
-
        }
 }

File Changes:

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

File [modified]: DefaultProxyBuilder.cs
Delta lines: +1 -3
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/AttributeDisassembler.cs  
    2009-11-29 00:42:54 UTC (rev 6369)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/AttributeDisassembler.cs  
    2009-11-29 08:05:35 UTC (rev 6370)
@@ -28,7 +28,6 @@
                        }
                        catch (Exception ex)
                        {
-
                                // there is no real way to log a warning here...
                                return HandleError(type,ex);
                        }
@@ -43,7 +42,7 @@
                protected virtual CustomAttributeBuilder HandleError(Type 
attributeType, Exception exception)
                {
                        // ouch...
-                       string message = "Dynamic Proxy was unable to 
disassemble attribute " + attributeType.Name +
+                       string message = "DynamicProxy was unable to 
disassemble attribute " + attributeType.Name +
                                         " using default AttributeDisassembler. 
" +
                                         "To handle the disassembly process 
properly implement the IAttributeDisassembler interface, " +
                                         "and register your disassembler to 
handle this type of attributes using " +
@@ -152,7 +151,6 @@
                                }
                        }
 
-
                        PropertyInfo bestMatch = null;
                        //now we try to find it by type

File [modified]: IProxyBuilder.cs
Delta lines: +0 -2
===================================================================

--- DynamicProxy/trunk/src/Castle.DynamicProxy/ModuleScope.cs   2009-11-29 
00:42:54 UTC (rev 6369)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/ModuleScope.cs   2009-11-29 
08:05:35 UTC (rev 6370)
@@ -25,8 +25,6 @@
 
 #if SILVERLIGHT
        using Castle.DynamicProxy.SilverlightExtensions;
-#else
-
 #endif
 

File [modified]: ModuleScope.cs
Delta lines: +0 -3
===================================================================

--- DynamicProxy/trunk/src/Castle.DynamicProxy/ProxyGenerationOptions.cs        
2009-11-29 00:42:54 UTC (rev 6369)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/ProxyGenerationOptions.cs        
2009-11-29 08:05:35 UTC (rev 6370)
@@ -39,7 +39,6 @@
 #endif
                private MixinData mixinData; // this is calculated dynamically 
on proxy type creation
 
-
                /// <summary>
                /// Initializes a new instance of the <see 
cref="ProxyGenerationOptions"/> class.
                /// </summary>
@@ -58,7 +57,6 @@
                {
                }
 
-
 #if SILVERLIGHT
 #warning What to do?
 #else
@@ -154,7 +152,6 @@
                        get { return mixins == null ? false : mixins.Count != 
0; }
                }
 
-
                public override bool Equals(object obj)
                {

File [modified]: ProxyGenerationOptions.cs
Delta lines: +17 -1
===================================================================

--- DynamicProxy/trunk/src/Castle.DynamicProxy/ProxyGenerator.cs        
2009-11-29 00:42:54 UTC (rev 6369)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/ProxyGenerator.cs        
2009-11-29 08:05:35 UTC (rev 6370)
@@ -12,7 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-
 namespace Castle.DynamicProxy
 {
        using System;
@@ -24,6 +23,7 @@
 #endif
        using System.Text;
        using Castle.Core.Interceptor;
+       using Castle.Core.Logging;
 
        /// <summary>
        /// Provides proxy objects for classes and interfaces.
@@ -31,6 +31,7 @@
        [CLSCompliant(true)]
        public class ProxyGenerator
        {
+               private ILogger logger = NullLogger.Instance;
                private readonly IProxyBuilder proxyBuilder;
 
                #region Constructors
@@ -42,6 +43,8 @@
                public ProxyGenerator(IProxyBuilder builder)
                {
                        proxyBuilder = builder;
+
+                       Logger = new TraceLogger("Castle.DynamicProxy", 
LoggerLevel.Warn);
                }
 
                /// <summary>
@@ -56,6 +59,19 @@
                #region Properties
 
                /// <summary>
+               /// Gets or sets the <see cref="ILogger"/> that this <see 
cref="ProxyGenerator"/> log to.
+               /// </summary>
+               public ILogger Logger
+               {
+                       get { return logger; }
+                       set
+                       {
+                               logger = value;
+                               proxyBuilder.Logger = value;
+                       }
+               }
+
+               /// <summary>
                /// Gets the proxy builder instance used to generate proxy 
types.
                /// </summary>

File [modified]: ProxyGenerator.cs
Delta lines: +24 -32
===================================================================

--- DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/BasePEVerifyTestCase.cs    
2009-11-29 00:42:54 UTC (rev 6369)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/BasePEVerifyTestCase.cs    
2009-11-29 08:05:35 UTC (rev 6370)
@@ -21,31 +21,30 @@
        using NUnit.Framework;
 
 #if !MONO && !SILVERLIGHT // mono doesn't have PEVerify
-         [SetUpFixture]
-         public class FindPeVerify
-         {
-                 [SetUp]
-                 public void FindPeVerifySetUp()
-                 {
-                       var peVerifyProbingPaths = 
Settings.Default.PeVerifyProbingPaths;
-                       foreach (var path in peVerifyProbingPaths)
-                       {
-                               var file = Path.Combine(path, "peverify.exe");
-                               if (File.Exists(file))
-                               {
-                                       PeVerifyPath = file;
-                                       return;
-                               }
-                       }
-                       throw new FileNotFoundException(
+       [SetUpFixture]
+       public class FindPeVerify
+       {
+               [SetUp]
+               public void FindPeVerifySetUp()
+               {
+                       var peVerifyProbingPaths = 
Settings.Default.PeVerifyProbingPaths;
+                       foreach (var path in peVerifyProbingPaths)
+                       {
+                               var file = Path.Combine(path, "peverify.exe");
+                               if (File.Exists(file))
+                               {
+                                       PeVerifyPath = file;
+                                       return;
+                               }
+                       }
+                       throw new FileNotFoundException(
                                "Please check the PeVerifyProbingPaths 
configuration setting and set it to the folder where peverify.exe is located");
-                 }
+               }
 
-               public static string PeVerifyPath { get; set; }
-         }
-#endif 
+               public static string PeVerifyPath { get; set; }
+       }
+#endif
 
-
        public abstract class BasePEVerifyTestCase
        {
                protected ProxyGenerator generator;
@@ -77,7 +76,6 @@
                }
 
 #if !MONO && !SILVERLIGHT // mono doesn't have PEVerify
-
                [TearDown]
                public virtual void TearDown()
                {
@@ -90,11 +88,9 @@
                        }
                }
 
-
                public void RunPEVerifyOnGeneratedAssembly(string assemblyPath)
                {
                        Process process = new Process();
-
                        process.StartInfo.FileName = FindPeVerify.PeVerifyPath;
                        process.StartInfo.RedirectStandardOutput = true;
                        process.StartInfo.UseShellExecute = false;
@@ -115,17 +111,13 @@
                                Assert.Fail("PeVerify reported error(s): " + 
Environment.NewLine + processOutput, result);
                        }
                }
-
 #else
-
-
-#if !SILVERLIGHT
+               #if !SILVERLIGHT
                [TearDown]
-#endif
-               public virtual void TearDown ()
+               #endif
+               public virtual void TearDown()
                {
                }
-
 #endif
        }

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

File [modified]: BasePEVerifyTestCase.cs
Delta lines: +1 -0
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/Castle.DynamicProxy.Tests-vs2008.csproj
    2009-11-29 00:42:54 UTC (rev 6369)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/Castle.DynamicProxy.Tests-vs2008.csproj
    2009-11-29 08:05:35 UTC (rev 6370)
@@ -186,6 +186,7 @@
     <Compile Include="Interfaces\Two.cs" />
     <Compile Include="InvocationMethodInvocationTargetTestCase.cs" />
     <Compile Include="InvocationTypesCachingTestCase.cs" />
+    <Compile Include="LoggingTestCase.cs" />
     <Compile Include="MethodEquivalenceTestCase.cs" />
     <Compile Include="MixinDataTestCase.cs" />

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

--- DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/Classes/SimpleClass.cs     
2009-11-29 00:42:54 UTC (rev 6369)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/Classes/SimpleClass.cs     
2009-11-29 08:05:35 UTC (rev 6370)
@@ -14,8 +14,6 @@
 
 namespace Castle.DynamicProxy.Tests.Classes
 {
-       using System;
-
        public class SimpleClass
        {

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

--- DynamicProxy/trunk/src/Changes.txt  2009-11-29 00:42:54 UTC (rev 6369)
+++ DynamicProxy/trunk/src/Changes.txt  2009-11-29 08:05:35 UTC (rev 6370)
@@ -1,5 +1,7 @@
 Unreleased Changes
 ==================
+- Fixed DYNPROXY-ISSUE-120: Add logging to DynamicProxy.
+  Introduced basic logging for cache hit/miss, methods that cannot be 
intercepted, and overriding Equals/GetHashCode.
 
 - Fixed DYNPROXY-ISSUE-94 - CreateProxyWithTarget fails if you use 
ProxyGenerationHook

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

File [modified]: SimpleClass.cs
Delta lines: +416 -0
===================================================================

--- DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/LoggingTestCase.cs         
                (rev 0)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy.Tests/LoggingTestCase.cs 
2009-11-29 08:05:35 UTC (rev 6370)
@@ -0,0 +1,416 @@
+// Copyright 2004-2009 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 System.Reflection;
+       using Castle.Core.Logging;
+       using NUnit.Framework;
+
+       [TestFixture]
+       public class LoggingTestCase
+       {
+               [Test]
+               public void CacheMiss()
+               {
+                       // Arrange
+                       CollectingLogger logger = new CollectingLogger();
+                       ProxyGenerator generator = new ProxyGenerator { Logger 
= logger };
+
+                       // Act
+                       generator.CreateClassProxy<EmptyClass>();
+
+                       // Assert
+                       Assert.That(logger.RecordedMessage(LoggerLevel.Debug, 
"No cached proxy type was found for target type " +
+                               
"Castle.DynamicProxy.Tests.LoggingTestCase+EmptyClass."));
+               }
+
+               [Test]
+               public void CacheHitClassProxy()
+               {
+                       // Arrange
+                       CollectingLogger logger = new CollectingLogger();
+                       ProxyGenerator generator = new ProxyGenerator { Logger 
= logger };
+
+                       // Act
+                       generator.CreateClassProxy<EmptyClass>();
+                       generator.CreateClassProxy<EmptyClass>();
+
+                       // Assert
+                       Assert.That(logger.RecordedMessage(LoggerLevel.Debug, 
"Found cached proxy type Castle.Proxies.EmptyClassProxy " +
+                               "for target type 
Castle.DynamicProxy.Tests.LoggingTestCase+EmptyClass."));
+               }
+
+               [Test]
+               public void CacheHitInterfaceProxy()
+               {
+                       // Arrange
+                       CollectingLogger logger = new CollectingLogger();
+                       ProxyGenerator generator = new ProxyGenerator { Logger 
= logger };
+
+                       // Act
+                       
generator.CreateInterfaceProxyWithoutTarget<IEmptyInterface>();
+                       
generator.CreateInterfaceProxyWithoutTarget<IEmptyInterface>();
+
+                       // Assert
+                       Assert.That(logger.RecordedMessage(LoggerLevel.Debug, 
"Found cached proxy type Castle.Proxies.IEmptyInterfaceProxy " +
+                               "for target type 
Castle.DynamicProxy.Tests.LoggingTestCase+IEmptyInterface."));
+               }
+
+               [Test]
+               public void 
ProxyGenerationOptionsEqualsAndGetHashCodeNotOverriden()
+               {
+                       // Arrange
+                       CollectingLogger logger = new CollectingLogger();
+                       ProxyGenerator generator = new ProxyGenerator { Logger 
= logger };
+
+                       // Act
+                       ProxyGenerationOptions options = new 
ProxyGenerationOptions {
+                               Hook = new EmptyHook()
+                       };
+                       generator.CreateClassProxy(typeof(EmptyClass), options);
+
+                       // Assert
+                       Assert.That(logger.RecordedMessage(LoggerLevel.Warn, 
"The IProxyGenerationHook type " +
+                               
"Castle.DynamicProxy.Tests.LoggingTestCase+EmptyHook does not override both 
Equals and GetHashCode. " +
+                               "If these are not correctly overridden caching 
will fail to work causing performance problems."));
+               }
+
+               [Test]
+               public void ExcludedNonVirtualMethods()
+               {
+                       // Arrange
+                       CollectingLogger logger = new CollectingLogger();
+                       ProxyGenerator generator = new ProxyGenerator { Logger 
= logger };
+
+                       // Act
+                       generator.CreateClassProxy<NonVirtualMethodClass>();
+
+                       // Assert
+                       Assert.That(logger.RecordedMessage(LoggerLevel.Debug, 
"Excluded non-virtual method ClassMethod on " +
+                               
"Castle.DynamicProxy.Tests.LoggingTestCase+NonVirtualMethodClass because it 
cannot be intercepted."));
+                       Assert.That(logger.RecordedMessage(LoggerLevel.Debug, 
"Excluded sealed method InterfaceMethod on " +
+                               
"Castle.DynamicProxy.Tests.LoggingTestCase+NonVirtualMethodClass because it 
cannot be intercepted."));
+               }
+
+               [Test]
+               public void FoundExplicitlyImplementedInterfaceMethods()
+               {
+                       // Arrange
+                       CollectingLogger logger = new CollectingLogger();
+                       ProxyGenerator generator = new ProxyGenerator { Logger 
= logger };
+
+                       // Act
+                       
generator.CreateClassProxy<ClassWithInterfaceMethodExplicitlyImplemented>();
+
+                       // Assert
+                       Assert.That(logger.RecordedMessage(LoggerLevel.Debug, 
"Excluded explicitly implemented interface method " +
+                               
"Castle.DynamicProxy.Tests.LoggingTestCase.ISingleMethodInterface.InterfaceMethod
 on type " +
+                               
"Castle.DynamicProxy.Tests.LoggingTestCase+ClassWithInterfaceMethodExplicitlyImplemented
 " +
+                               "because it cannot be intercepted."));
+               }
+
+               #region Test Types
+
+               public class EmptyClass
+               {
+               }
+
+               public interface IEmptyInterface
+               {
+               }
+
+               public interface ISingleMethodInterface
+               {
+                       void InterfaceMethod();
+               }
+
+               public class NonVirtualMethodClass : ISingleMethodInterface
+               {
+                       public void ClassMethod()
+                       {
+                       }
+
+                       public void InterfaceMethod()
+                       {
+                       }
+               }
+
+               public class ClassWithInterfaceMethodExplicitlyImplemented : 
ISingleMethodInterface
+               {
+                       void ISingleMethodInterface.InterfaceMethod()
+                       {
+                       }
+               }
+
+               public class EmptyHook : IProxyGenerationHook
+               {
+                       public bool ShouldInterceptMethod(Type type, MethodInfo 
methodInfo)
+                       {
+                               return true;
+                       }
+
+                       public void NonVirtualMemberNotification(Type type, 
MemberInfo memberInfo)
+                       {
+                       }
+
+                       public void MethodsInspected()
+                       {
+                       }
+               }
+
+               #endregion
+       }
+
+       #region CollectingLogger
+
+       public class CollectingLogger : ILogger
+       {
+               private readonly List<string> messages = new List<string>();
+
+               public bool RecordedMessage(LoggerLevel level, string message)
+               {
+                       return messages.Contains(level.ToString().ToUpper() + 
": " + message);
+               }
+
+               public void Debug(string message)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void Debug(string message, Exception exception)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void Debug(string format, params object[] args)
+               {
+                       messages.Add("DEBUG: " + string.Format(format, args));
+               }
+
+               public void DebugFormat(string format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void DebugFormat(Exception exception, string format, 
params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void DebugFormat(IFormatProvider formatProvider, string 
format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void DebugFormat(Exception exception, IFormatProvider 
formatProvider, string format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void Info(string message)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void Info(string message, Exception exception)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void Info(string format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void InfoFormat(string format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void InfoFormat(Exception exception, string format, 
params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void InfoFormat(IFormatProvider formatProvider, string 
format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void InfoFormat(Exception exception, IFormatProvider 
formatProvider, string format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void Warn(string message)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void Warn(string message, Exception exception)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void Warn(string format, params object[] args)
+               {
+                       messages.Add("WARN: " + string.Format(format, args));
+               }
+
+               public void WarnFormat(string format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void WarnFormat(Exception exception, string format, 
params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void WarnFormat(IFormatProvider formatProvider, string 
format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void WarnFormat(Exception exception, IFormatProvider 
formatProvider, string format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void Error(string message)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void Error(string message, Exception exception)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void Error(string format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void ErrorFormat(string format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void ErrorFormat(Exception exception, string format, 
params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void ErrorFormat(IFormatProvider formatProvider, string 
format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void ErrorFormat(Exception exception, IFormatProvider 
formatProvider, string format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void Fatal(string message)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void Fatal(string message, Exception exception)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void Fatal(string format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void FatalFormat(string format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void FatalFormat(Exception exception, string format, 
params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void FatalFormat(IFormatProvider formatProvider, string 
format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void FatalFormat(Exception exception, IFormatProvider 
formatProvider, string format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void FatalError(string message)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void FatalError(string message, Exception exception)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public void FatalError(string format, params object[] args)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public ILogger CreateChildLogger(string loggerName)
+               {
+                       throw new NotImplementedException();
+               }
+
+               public bool IsDebugEnabled
+               {
+                       get { return true; }
+               }
+
+               public bool IsInfoEnabled
+               {
+                       get { return true; }
+               }
+
+               public bool IsWarnEnabled
+               {
+                       get { return true; }
+               }
+
+               public bool IsErrorEnabled
+               {
+                       get { return true; }
+               }
+
+               public bool IsFatalEnabled
+               {
+                       get { return true; }
+               }
+
+               public bool IsFatalErrorEnabled
+               {
+                       get { return true; }
+               }
+       }
+
+       #endregion
+}

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

File [modified]: ClassMembersCollector.cs
Delta lines: +11 -7
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/ClassProxyTargetContributor.cs
      2009-11-29 00:42:54 UTC (rev 6369)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/ClassProxyTargetContributor.cs
      2009-11-29 08:05:35 UTC (rev 6370)
@@ -19,13 +19,14 @@
        using System.Diagnostics;
        using System.Reflection;
        using System.Reflection.Emit;
+       using Castle.Core.Logging;
+       using Castle.DynamicProxy.Generators;
+       using Castle.DynamicProxy.Generators.Emitters;
+       using Castle.DynamicProxy.Generators.Emitters.SimpleAST;
 
-       using Generators;
-       using Generators.Emitters;
-       using Generators.Emitters.SimpleAST;
-
        public class ClassProxyTargetContributor : CompositeTypeContributor
        {
+               private ILogger logger = NullLogger.Instance;
                private readonly Type targetType;
                private readonly IList<MethodInfo> methodsToSkip;
 
@@ -35,13 +36,17 @@
                        this.methodsToSkip = methodsToSkip;
                }
 
+               public ILogger Logger
+               {
+                       get { return logger; }
+                       set { logger = value; }
+               }
 
-
                public override void 
CollectElementsToProxy(IProxyGenerationHook hook)
                {
                        Debug.Assert(hook != null, "hook != null");
 
-                       var targetItem = new ClassMembersCollector(targetType, 
this);
+                       var targetItem = new ClassMembersCollector(targetType, 
this) { Logger = logger };
                        targetItem.CollectMembersToProxy(hook);
                        targets.Add(targetItem);
 
@@ -54,7 +59,6 @@
                                item.CollectMembersToProxy(hook);
                                targets.Add(item);
                        }
-
                }
 

File [modified]: ClassProxyTargetContributor.cs
Delta lines: +24 -9
===================================================================

--- DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/MembersCollector.cs 
2009-11-29 00:42:54 UTC (rev 6369)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/MembersCollector.cs 
2009-11-29 08:05:35 UTC (rev 6370)
@@ -17,20 +17,22 @@
        using System;
        using System.Collections.Generic;
        using System.Reflection;
-       using Generators;
+       using Castle.Core.Logging;
+       using Castle.DynamicProxy.Generators;
 
        public abstract class MembersCollector
        {
                private const BindingFlags Flags = BindingFlags.Public | 
BindingFlags.NonPublic | BindingFlags.Instance;
+
                protected readonly bool onlyProxyVirtual;
                protected readonly InterfaceMapping map;
+               private ILogger logger = NullLogger.Instance;
                private IList<MethodInfo> checkedMethods = new 
List<MethodInfo>();
                private readonly IDictionary<PropertyInfo, PropertyToGenerate> 
properties = new Dictionary<PropertyInfo, PropertyToGenerate>();
                private readonly IDictionary<EventInfo, EventToGenerate> events 
= new Dictionary<EventInfo, EventToGenerate>();
                private readonly IDictionary<MethodInfo, MethodToGenerate> 
methodsToProxy = new Dictionary<MethodInfo, MethodToGenerate>();
                private readonly Type type;
 
-
                protected readonly ITypeContributor contributor;
 
                protected MembersCollector(Type type, ITypeContributor 
contributor, bool onlyProxyVirtual, InterfaceMapping map)
@@ -41,6 +43,12 @@
                        this.map = map;
                }
 
+               public ILogger Logger
+               {
+                       get { return logger; }
+                       set { logger = value; }
+               }
+
                public IEnumerable<MethodToGenerate> Methods
                {
                        get { return methodsToProxy.Values; }
@@ -181,8 +189,8 @@
 
                protected virtual MethodInfo GetMethodOnTarget(MethodInfo 
method)
                {
-                       var index = Array.IndexOf(map.InterfaceMethods, method);
-                       if(index==-1)
+                       int index = Array.IndexOf(map.InterfaceMethods, method);
+                       if (index == -1)
                        {
                                return null;
                        }
@@ -190,7 +198,6 @@
                        return map.TargetMethods[index];
                }
 
-
                /// <summary>
                /// Checks if the method is public or protected.
                /// </summary>
@@ -201,7 +208,6 @@
 #if SILVERLIGHT
                        return method.IsPublic || method.IsFamily || 
method.IsFamilyOrAssembly;
 #else
-
                        if (method.IsPublic
                            || method.IsFamily
                            || method.IsFamilyAndAssembly
@@ -215,6 +221,13 @@
                                return true;
                        }
 
+                       // Explicitly implemented interface method on class
+                       if (method.IsPrivate && method.IsFinal)
+                       {
+                               Logger.Debug("Excluded explicitly implemented 
interface method {0} on type {1} because it cannot be intercepted.",
+                                       method.Name, 
method.DeclaringType.FullName);
+                       }
+
                        return false;
 #endif
                }
@@ -231,7 +244,10 @@
                {
                        // we can never intercept a sealed (final) method
                        if (method.IsFinal)
+                       {
+                               Logger.Debug("Excluded sealed method {0} on {1} 
because it cannot be intercepted.", method.Name, method.DeclaringType.FullName);
                                return false;
+                       }
 
                        bool isInternalsAndNotVisibleToDynamicProxy = 
InternalsHelper.IsInternal(method);
                        if (isInternalsAndNotVisibleToDynamicProxy)
@@ -248,9 +264,10 @@
 #if SILVERLIGHT
                                if (method.DeclaringType != typeof(object))
 #else
-                               if (method.DeclaringType != typeof (object) && 
method.DeclaringType != typeof (MarshalByRefObject))
+                               if (method.DeclaringType != typeof(object) && 
method.DeclaringType != typeof(MarshalByRefObject))
 #endif
                                {
+                                       Logger.Debug("Excluded non-virtual 
method {0} on {1} because it cannot be intercepted.", method.Name, 
method.DeclaringType.FullName);
                                        hook.NonVirtualMemberNotification(type, 
method);
                                }
 
@@ -274,7 +291,5 @@
 #endif
                        return hook.ShouldInterceptMethod(type, method);
                }
-
-
        }
 }

File [modified]: MembersCollector.cs
Delta lines: +13 -0
===================================================================

--- DynamicProxy/trunk/src/Castle.DynamicProxy/DefaultProxyBuilder.cs   
2009-11-29 00:42:54 UTC (rev 6369)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/DefaultProxyBuilder.cs   
2009-11-29 08:05:35 UTC (rev 6370)
@@ -16,6 +16,7 @@
 {
        using System;
        using System.Collections.Generic;
+       using Castle.Core.Logging;
        using Castle.DynamicProxy.Generators;
 #if SILVERLIGHT
        using Castle.DynamicProxy.SilverlightExtensions;
@@ -26,6 +27,7 @@
        /// </summary>
        public class DefaultProxyBuilder : IProxyBuilder
        {
+               private ILogger logger = NullLogger.Instance;
                private readonly ModuleScope scope;
 
                /// <summary>
@@ -44,6 +46,13 @@
                {
                        this.scope = scope;
                }
+
+               public ILogger Logger
+               {
+                       get { return logger; }
+                       set { logger = value; }
+               }
+
                public ModuleScope ModuleScope
                {
                        get { return scope; }
@@ -67,6 +76,7 @@
                        AssertValidTypes(additionalInterfacesToProxy);
 
                        var generator = new ClassProxyGenerator(scope, 
classToProxy);
+                       generator.Logger = logger;
                        return 
generator.GenerateCode(additionalInterfacesToProxy, options);
                }
 
@@ -76,6 +86,7 @@
                        AssertValidTypes(additionalInterfacesToProxy);
 
                        var generator = new 
InterfaceProxyWithoutTargetGenerator(scope, interfaceToProxy);
+                       generator.Logger = logger;
                        return generator.GenerateCode(typeof(object), 
additionalInterfacesToProxy, options);
                }
 
@@ -86,6 +97,7 @@
                        AssertValidTypes(additionalInterfacesToProxy);
 
                        var generator = new 
InterfaceProxyWithTargetGenerator(scope, interfaceToProxy);
+                       generator.Logger = logger;
                        return generator.GenerateCode(targetType, 
additionalInterfacesToProxy, options);
                }
 
@@ -96,6 +108,7 @@
                        AssertValidTypes(additionalInterfacesToProxy);
 
                        var generator = new 
InterfaceProxyWithTargetInterfaceGenerator(scope, interfaceToProxy);
+                       generator.Logger = logger;
                        return generator.GenerateCode(interfaceToProxy, 
additionalInterfacesToProxy, options);
                }

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

File [modified]: AttributeDisassembler.cs
Delta lines: +41 -1
===================================================================

--- DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/BaseProxyGenerator.cs 
2009-11-29 00:42:54 UTC (rev 6369)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/BaseProxyGenerator.cs 
2009-11-29 08:05:35 UTC (rev 6370)
@@ -21,6 +21,7 @@
        using System.Runtime.Serialization;
        using System.Xml.Serialization;
        using Castle.Core.Interceptor;
+       using Castle.Core.Logging;
        using Castle.DynamicProxy.Generators.Emitters;
        using Castle.DynamicProxy.Generators.Emitters.CodeBuilders;
        using Castle.DynamicProxy.Generators.Emitters.SimpleAST;
@@ -35,6 +36,7 @@
        /// </summary>
        public abstract class BaseProxyGenerator
        {
+               private ILogger logger = NullLogger.Instance;
                private readonly ModuleScope scope;
                private ProxyGenerationOptions proxyGenerationOptions;
 
@@ -46,6 +48,12 @@
                        this.targetType = targetType;
                }
 
+               public ILogger Logger
+               {
+                       get { return logger; }
+                       set { logger = value; }
+               }
+
                protected ProxyGenerationOptions ProxyGenerationOptions
                {
                        get
@@ -254,12 +262,44 @@
 
                #endregion
 
+               protected void 
EnsureOptionsOverrideEqualsAndGetHashCode(ProxyGenerationOptions options)
+               {
+                       if (Logger.IsWarnEnabled)
+                       {
+                               // Check the proxy generation hook
+                               if 
(!OverridesEqualsAndGetHashCode(options.Hook.GetType()))
+                               {
+                                       Logger.Warn("The IProxyGenerationHook 
type {0} does not override both Equals and GetHashCode. " +
+                                               "If these are not correctly 
overridden caching will fail to work causing performance problems.",
+                                               
options.Hook.GetType().FullName);
+                               }
+
+                               // Interceptor selectors no longer need to 
override Equals and GetHashCode
+                       }
+               }
+
+               private bool OverridesEqualsAndGetHashCode(Type type)
+               {
+                       MethodInfo equalsMethod = type.GetMethod("Equals", 
BindingFlags.Public | BindingFlags.Instance);
+                       if (equalsMethod == null || equalsMethod.DeclaringType 
== typeof(object) || equalsMethod.IsAbstract)
+                       {
+                               return false;
+                       }
+
+                       MethodInfo getHashCodeMethod = 
type.GetMethod("GetHashCode", BindingFlags.Public | BindingFlags.Instance);
+                       if (getHashCodeMethod == null || 
getHashCodeMethod.DeclaringType == typeof(object) || 
getHashCodeMethod.IsAbstract)
+                       {
+                               return false;
+                       }
+
+                       return true;
+               }
+
                protected void AddMapping(Type @interface, ITypeContributor 
implementer, IDictionary<Type, ITypeContributor> mapping)
                {
                        Debug.Assert(implementer != null, "implementer != 
null");
                        Debug.Assert(@interface != null, "@interface != null");
                        Debug.Assert(@interface.IsInterface, 
"@interface.IsInterface");
-                       
 
                        if (!mapping.ContainsKey(@interface))

File [modified]: BaseProxyGenerator.cs
Delta lines: +1 -2
===================================================================

--- DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/CacheKey.cs   
2009-11-29 00:42:54 UTC (rev 6369)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/CacheKey.cs   
2009-11-29 08:05:35 UTC (rev 6370)
@@ -17,8 +17,7 @@
        using System;
        using System.Reflection;
 
-#if SILVERLIGHT
-#else
+#if !SILVERLIGHT
        [Serializable]
 #endif

File [modified]: CacheKey.cs
Delta lines: +11 -10
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/ClassProxyGenerator.cs    
    2009-11-29 00:42:54 UTC (rev 6369)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/ClassProxyGenerator.cs    
    2009-11-29 08:05:35 UTC (rev 6370)
@@ -62,25 +62,31 @@
                        using (UpgradableLock locker = new 
UpgradableLock(Scope.RWLock))
                        {
                                Type cacheType = GetFromCache(cacheKey);
-
                                if (cacheType != null)
                                {
+                                       Logger.Debug("Found cached proxy type 
{0} for target type {1}.", cacheType.FullName, targetType.FullName);
                                        return cacheType;
                                }
 
+                               // Upgrade the lock to a write lock, then read 
again. This is to avoid generating duplicate types
+                               // under heavy multithreaded load.
                                locker.Upgrade();
 
                                cacheType = GetFromCache(cacheKey);
-
                                if (cacheType != null)
                                {
+                                       Logger.Debug("Found cached proxy type 
{0} for target type {1}.", cacheType.FullName, targetType.FullName);
                                        return cacheType;
                                }
 
+                               // Log details about the cache miss
+                               Logger.Debug("No cached proxy type was found 
for target type {0}.", targetType.FullName);
+                               
EnsureOptionsOverrideEqualsAndGetHashCode(options);
+
                                ProxyGenerationOptions = options;
 
                                var name = 
Scope.NamingScope.GetUniqueName("Castle.Proxies." + targetType.Name + "Proxy");
-                               proxyType = GenerateType(name, 
interfaces,Scope.NamingScope.SafeSubScope());
+                               proxyType = GenerateType(name, interfaces, 
Scope.NamingScope.SafeSubScope());
 
                                AddToCache(cacheKey, proxyType);
                        }
@@ -91,7 +97,7 @@
                private Type GenerateType(string newName, Type[] interfaces, 
INamingScope namingScope)
                {
                        IEnumerable<ITypeContributor> contributors;
-                       var implementedInterfaces = 
GetTypeImplementerMapping(interfaces, out contributors,namingScope);
+                       var implementedInterfaces = 
GetTypeImplementerMapping(interfaces, out contributors, namingScope);
 
                        // Collect methods
                        foreach (var contributor in contributors)
@@ -111,8 +117,6 @@
                        // Fields generations
                        FieldReference interceptorsField = 
CreateInterceptorsField(emitter);
 
-
-
                        // Constructor
                        var cctor = GenerateStaticConstructor(emitter);
 
@@ -139,7 +143,6 @@
                        GenerateConstructors(emitter, targetType, 
constructorArguments.ToArray());
                        GenerateParameterlessConstructor(emitter, targetType, 
interceptorsField);
 
-
                        // Complete type initializer code body
                        CompleteInitCacheMethod(cctor.CodeBuilder);
 
@@ -155,7 +158,7 @@
                        var methodsToSkip = new List<MethodInfo>();
                        var proxyInstance = new 
ClassProxyInstanceContributor(targetType, methodsToSkip, interfaces);
                        // TODO: the trick with methodsToSkip is not very 
nice...
-                       var proxyTarget = new 
ClassProxyTargetContributor(targetType, methodsToSkip, namingScope);
+                       var proxyTarget = new 
ClassProxyTargetContributor(targetType, methodsToSkip, namingScope) { Logger = 
Logger };
                        IDictionary<Type, ITypeContributor> 
typeImplementerMapping = new Dictionary<Type, ITypeContributor>();
 
                        // Order of interface precedence:
@@ -195,10 +198,8 @@
                        // 3. then additional interfaces
                        foreach (var @interface in additionalInterfaces)
                        {
-                               
                                if (targetInterfaces.Contains(@interface))
                                {
-                                       
                                        if 
(typeImplementerMapping.ContainsKey(@interface)) continue;
 

File [modified]: ClassProxyGenerator.cs
Delta lines: +8 -3
===================================================================

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/InterfaceProxyWithTargetGenerator.cs
  2009-11-29 00:42:54 UTC (rev 6369)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/InterfaceProxyWithTargetGenerator.cs
  2009-11-29 08:05:35 UTC (rev 6370)
@@ -57,21 +57,27 @@
                        using (UpgradableLock locker = new 
UpgradableLock(Scope.RWLock))
                        {
                                Type cacheType = GetFromCache(cacheKey);
-
                                if (cacheType != null)
                                {
+                                       Logger.Debug("Found cached proxy type 
{0} for target type {1}.", cacheType.FullName, targetType.FullName);
                                        return cacheType;
                                }
 
+                               // Upgrade the lock to a write lock, then read 
again. This is to avoid generating duplicate types
+                               // under heavy multithreaded load.
                                locker.Upgrade();
 
                                cacheType = GetFromCache(cacheKey);
-
                                if (cacheType != null)
                                {
+                                       Logger.Debug("Found cached proxy type 
{0} for target type {1}.", cacheType.FullName, targetType.FullName);
                                        return cacheType;
                                }
 
+                               // Log details about the cache miss
+                               Logger.Debug("No cached proxy type was found 
for target type {0}.", targetType.FullName);
+                               
EnsureOptionsOverrideEqualsAndGetHashCode(options);
+
                                ProxyGenerationOptions = options;
 
                                var name = 
Scope.NamingScope.GetUniqueName("Castle.Proxies." + targetType.Name + "Proxy");
@@ -229,7 +235,6 @@
                        var additionalInterfaces = 
TypeUtil.GetAllInterfaces(interfaces);
                        var target = 
AddMappingForTargetType(typeImplementerMapping, proxyTargetType, 
targetInterfaces, additionalInterfaces,namingScope);
 
-
                        // 2. then mixins
                        if (ProxyGenerationOptions.HasMixins)

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

--- 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/InvocationTypeGenerator.cs
    2009-11-29 00:42:54 UTC (rev 6369)
+++ 
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/InvocationTypeGenerator.cs
    2009-11-29 08:05:35 UTC (rev 6370)
@@ -237,10 +237,6 @@
                        invokeMethodOnTarget.CodeBuilder.AddStatement(new 
ReturnStatement());
                }
 
-
-
-
-
                protected void 
CreateEmptyIInvocationInvokeOnTarget(AbstractTypeEmitter nested)
                {

File [modified]: InvocationTypeGenerator.cs
Delta lines: +6 -0
===================================================================

--- DynamicProxy/trunk/src/Castle.DynamicProxy/IProxyBuilder.cs 2009-11-29 
00:42:54 UTC (rev 6369)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/IProxyBuilder.cs 2009-11-29 
08:05:35 UTC (rev 6370)
@@ -17,6 +17,7 @@
        using System;
        using System.Runtime.CompilerServices;
        using Castle.Core.Interceptor;
+       using Castle.Core.Logging;
        using Castle.DynamicProxy.Generators;
 
        /// <summary>
@@ -25,6 +26,11 @@
        public interface IProxyBuilder
        {
                /// <summary>
+               /// Gets or sets the <see cref="ILogger"/> that this <see 
cref="ProxyGenerator"/> logs to.
+               /// </summary>
+               ILogger Logger { get; set; }
+
+               /// <summary>
                /// Gets the <see cref="ModuleScope"/> associated with this 
builder.
                /// </summary>

Directory: /DynamicProxy/trunk/src/
===================================

File [modified]: Changes.txt
Delta lines: +0 -0
===================================================================

--

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