diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AdvisedProxy.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AdvisedProxy.cs index 6c4b80a7..0867baec 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AdvisedProxy.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AdvisedProxy.cs @@ -1,7 +1,7 @@ -#region License - +#region License + /* - * Copyright © 2002-2005 the original author or authors. + * Copyright © 2002-2009 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. @@ -14,420 +14,413 @@ * 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.Collections; -using System.Collections.Specialized; -using System.Diagnostics; -using System.Reflection; -using System.Runtime.Serialization; -using System.Security.Permissions; - -using AopAlliance.Aop; -using AopAlliance.Intercept; -using Spring.Aop.Target; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// Represents the AOP configuration data built-in with the proxy. - /// - /// Bruno Baia - [Serializable] - public class AdvisedProxy : IAdvised //, ISerializable - { - #region Fields - - /// - /// Should we use dynamic reflection for method invocation ? - /// - public static bool UseDynamicReflection; - - /// - /// Optimization fields - /// - private static IList EmptyList = ArrayList.ReadOnly(new ArrayList()); - - /// - /// IAdvised delegate - /// - public IAdvised m_advised; - - /// - /// Array of introduction delegates - /// - public IAdvice[] m_introductions; - - /// - /// Target source wrapper - /// - public ITargetSourceWrapper m_targetSourceWrapper; - - /// - /// Type of target object. - /// - public Type m_targetType; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the class. - /// - static AdvisedProxy() - { - string appSettingsKey = typeof(AdvisedProxy).FullName + ".UseDynamicReflection"; - NameValueCollection appSettings = - ConfigurationUtils.GetSection("appSettings") as NameValueCollection; - - if (appSettings != null && StringUtils.HasLength(appSettings[appSettingsKey])) - { - UseDynamicReflection = bool.Parse(appSettings[appSettingsKey]); - } - else - { - UseDynamicReflection = true; - } - } - - /// - /// Creates a new instance of the class. - /// - public AdvisedProxy() - {} - - /// - /// Creates a new instance of the class. - /// - /// The proxy configuration. - protected AdvisedProxy(IAdvised advised) - { - m_advised = advised; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// The proxy configuration. - /// The proxy. - public AdvisedProxy(IAdvised advised, IAopProxy proxy) - { - Initialize(advised, proxy); - } - - /// - /// Deserialization constructor. - /// - /// Serialization data. - /// Serialization context. - protected AdvisedProxy(SerializationInfo info, StreamingContext context) - { - m_advised = (IAdvised) info.GetValue("advised", typeof(IAdvised)); - m_introductions = (IAdvice[]) info.GetValue("introductions", typeof(IAdvice[])); - m_targetSourceWrapper = (ITargetSourceWrapper) info.GetValue("tsWrapper", typeof(ITargetSourceWrapper)); - m_targetType = (Type) info.GetValue("targetType", typeof(Type)); - } - - /// - /// Serializes this instance. - /// - /// Serialization data. - /// Serialization context. - [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] - protected virtual void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("advised", m_advised); - info.AddValue("introductions", m_introductions); - info.AddValue("tsWrapper", m_targetSourceWrapper); - info.AddValue("targetType", m_targetType); - } - - #endregion - - #region Protected Methods - - /// - /// Initialization method. - /// - /// The proxy configuration. - /// - /// The current implementation. - /// - protected void Initialize(IAdvised advised, IAopProxy proxy) - { - this.m_advised = advised; - this.m_targetType = advised.TargetSource.TargetType; - - // initialize target - if (advised.TargetSource.IsStatic) - { - this.m_targetSourceWrapper = new StaticTargetSourceWrapper(advised.TargetSource); - } - else - { - this.m_targetSourceWrapper = new DynamicTargetSourceWrapper(advised.TargetSource); - } - - // initialize introduction advice - this.m_introductions = new IAdvice[advised.Introductions.Length]; - for (int i = 0; i < advised.Introductions.Length; i++) - { - this.m_introductions[i] = advised.Introductions[i].Advice; - - // set target proxy on introduction instance if it implements ITargetAware - if (this.m_introductions[i] is ITargetAware) - { - ((ITargetAware) this.m_introductions[i]).TargetProxy = proxy; - } - } - } - - #endregion - - #region Public Methods - - /// - /// Invokes intercepted methods using reflection - /// - /// proxy object - /// target object to invoke method on - /// target type - /// taget method to invoke - /// The method to invoke on proxy. - /// method arguments - /// interceptor chain - /// value returned by invocation chain - public object Invoke(object proxy, object target, Type targetType, - MethodInfo targetMethod, MethodInfo proxyMethod, object[] args, IList interceptors) - { - IMethodInvocation invocation = null; - if (UseDynamicReflection) - { - invocation = new DynamicMethodInvocation( - proxy, target, targetMethod, proxyMethod, args, targetType, interceptors); - } - else - { - invocation = new ReflectiveMethodInvocation( - proxy, target, targetMethod, proxyMethod, args, targetType, interceptors); - } - return invocation.Proceed(); - } - - /// - /// Returns a list of method interceptors - /// - /// target type - /// target method - /// list of inteceptors for the specified method - public IList GetInterceptors(Type targetType, MethodInfo method) - { - if (m_advised.Advisors.Length == 0) - { - return EmptyList; - } - else - { - return m_advised.AdvisorChainFactory.GetInterceptors(m_advised, this, method, targetType); - } - } - - #endregion - - #region IAdvised Members - - bool IAdvised.ExposeProxy - { - get { return m_advised.ExposeProxy; } - } - - IAdvisorChainFactory IAdvised.AdvisorChainFactory - { - get { return m_advised.AdvisorChainFactory; } - } - - bool IAdvised.ProxyTargetType - { - get { return m_advised.ProxyTargetType; } - } - - bool IAdvised.ProxyTargetAttributes - { - get { return m_advised.ProxyTargetAttributes; } - } - - IAdvisor[] IAdvised.Advisors - { - get { return m_advised.Advisors; } - } - - IIntroductionAdvisor[] IAdvised.Introductions - { - get { return m_advised.Introductions; } - } - - Type[] IAdvised.Interfaces - { - get { return m_advised.Interfaces; } - } - - IDictionary IAdvised.InterfaceMap - { - get { return m_advised.InterfaceMap; } - } - - bool IAdvised.IsFrozen - { - get { return m_advised.IsFrozen; } - } - - ITargetSource IAdvised.TargetSource - { - get { return m_advised.TargetSource; } - } - - bool IAdvised.IsSerializable - { - get { return m_advised.IsSerializable; } - } - - /// - /// Adds the supplied to the end (or tail) - /// of the advice (interceptor) chain. - /// - /// - /// The to be added. - /// - /// - /// - public void AddAdvice(IAdvice advice) - { - this.m_advised.AddAdvice(advice); - } - - /// - /// Adds the supplied to the supplied - /// in the advice (interceptor) chain. - /// - /// - /// The zero (0) indexed position (from the head) at which the - /// supplied is to be inserted into the - /// advice (interceptor) chain. - /// - /// - /// The to be added. - /// - /// - /// - public void AddAdvice(int position, IAdvice advice) - { - this.m_advised.AddAdvice(position, advice); - } - - bool IAdvised.IsInterfaceProxied(Type intf) - { - return m_advised.IsInterfaceProxied(intf); - } - - void IAdvised.AddAdvisors(IAdvisors advisors) - { - m_advised.AddAdvisors(advisors); - } - - void IAdvised.AddAdvisor(IAdvisor advisor) - { - m_advised.AddAdvisor(advisor); - } - - void IAdvised.AddAdvisor(int pos, IAdvisor advisor) - { - m_advised.AddAdvisor(pos, advisor); - } - - void IAdvised.AddIntroduction(IIntroductionAdvisor advisor) - { - m_advised.AddIntroduction(advisor); - } - - void IAdvised.AddIntroduction(int pos, IIntroductionAdvisor advisor) - { - m_advised.AddIntroduction(pos, advisor); - } - - int IAdvised.IndexOf(IAdvisor advisor) - { - return m_advised.IndexOf(advisor); - } - - int IAdvised.IndexOf(IIntroductionAdvisor advisor) - { - return m_advised.IndexOf(advisor); - } - - bool IAdvised.RemoveAdvisor(IAdvisor advisor) - { - return m_advised.RemoveAdvisor(advisor); - } - - void IAdvised.RemoveAdvisor(int index) - { - m_advised.RemoveAdvisor(index); - } - - bool IAdvised.RemoveAdvice(IAdvice advice) - { - return m_advised.RemoveAdvice(advice); - } - - bool IAdvised.RemoveIntroduction(IIntroductionAdvisor advisor) - { - return m_advised.RemoveIntroduction(advisor); - } - - void IAdvised.RemoveIntroduction(int index) - { - m_advised.RemoveIntroduction(index); - } - - void IAdvised.ReplaceIntroduction(int index, IIntroductionAdvisor advisor) - { - m_advised.ReplaceIntroduction(index, advisor); - } - - bool IAdvised.ReplaceAdvisor(IAdvisor a, IAdvisor b) - { - return m_advised.ReplaceAdvisor(a, b); - } - - string IAdvised.ToProxyConfigString() - { - return m_advised.ToProxyConfigString(); - } - - #endregion - - #region ITargetTypeAware implementation - - /// - /// Gets the target type behind the implementing object. - /// Ttypically a proxy configuration or an actual proxy. - /// - /// The type of the target or null if not known. - public Type TargetType - { - get { return m_targetType; } - } - + */ + +#endregion + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Reflection; +using System.Runtime.Serialization; +using System.Security.Permissions; +using AopAlliance.Aop; +using AopAlliance.Intercept; +using Spring.Util; + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// Represents the AOP configuration data built-in with the proxy. + /// + /// Bruno Baia + [Serializable] + public class AdvisedProxy : IAdvised //, ISerializable + { + #region Fields + + /// + /// Should we use dynamic reflection for method invocation ? + /// + public static bool UseDynamicReflection; + + /// + /// Optimization fields + /// + private static IList EmptyList = ArrayList.ReadOnly(new ArrayList()); + + /// + /// IAdvised delegate + /// + public IAdvised m_advised; + + /// + /// Array of introduction delegates + /// + public IAdvice[] m_introductions; + + /// + /// Target source wrapper + /// + public ITargetSourceWrapper m_targetSourceWrapper; + + /// + /// Type of target object. + /// + public Type m_targetType; + #endregion - } + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the class. + /// + static AdvisedProxy() + { + string appSettingsKey = typeof(AdvisedProxy).FullName + ".UseDynamicReflection"; + NameValueCollection appSettings = + ConfigurationUtils.GetSection("appSettings") as NameValueCollection; + + if (appSettings != null && StringUtils.HasLength(appSettings[appSettingsKey])) + { + UseDynamicReflection = bool.Parse(appSettings[appSettingsKey]); + } + else + { + UseDynamicReflection = true; + } + } + + /// + /// Creates a new instance of the class. + /// + public AdvisedProxy() + { } + + /// + /// Creates a new instance of the class. + /// + /// The proxy configuration. + protected AdvisedProxy(IAdvised advised) + { + m_advised = advised; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// The proxy configuration. + /// The proxy. + public AdvisedProxy(IAdvised advised, IAopProxy proxy) + { + Initialize(advised, proxy); + } + + /// + /// Deserialization constructor. + /// + /// Serialization data. + /// Serialization context. + protected AdvisedProxy(SerializationInfo info, StreamingContext context) + { + m_advised = (IAdvised)info.GetValue("advised", typeof(IAdvised)); + m_introductions = (IAdvice[])info.GetValue("introductions", typeof(IAdvice[])); + m_targetSourceWrapper = (ITargetSourceWrapper)info.GetValue("tsWrapper", typeof(ITargetSourceWrapper)); + m_targetType = (Type)info.GetValue("targetType", typeof(Type)); + } + + /// + /// Serializes this instance. + /// + /// Serialization data. + /// Serialization context. + [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] + protected virtual void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("advised", m_advised); + info.AddValue("introductions", m_introductions); + info.AddValue("tsWrapper", m_targetSourceWrapper); + info.AddValue("targetType", m_targetType); + } + + #endregion + + #region Protected Methods + + /// + /// Initialization method. + /// + /// The proxy configuration. + /// + /// The current implementation. + /// + protected void Initialize(IAdvised advised, IAopProxy proxy) + { + this.m_advised = advised; + this.m_targetType = advised.TargetSource.TargetType; + + // initialize target + if (advised.TargetSource.IsStatic) + { + this.m_targetSourceWrapper = new StaticTargetSourceWrapper(advised.TargetSource); + } + else + { + this.m_targetSourceWrapper = new DynamicTargetSourceWrapper(advised.TargetSource); + } + + // initialize introduction advice + this.m_introductions = new IAdvice[advised.Introductions.Length]; + for (int i = 0; i < advised.Introductions.Length; i++) + { + this.m_introductions[i] = advised.Introductions[i].Advice; + + // set target proxy on introduction instance if it implements ITargetAware + if (this.m_introductions[i] is ITargetAware) + { + ((ITargetAware)this.m_introductions[i]).TargetProxy = proxy; + } + } + } + + #endregion + + #region Public Methods + + /// + /// Invokes intercepted methods using reflection + /// + /// proxy object + /// target object to invoke method on + /// target type + /// taget method to invoke + /// The method to invoke on proxy. + /// method arguments + /// interceptor chain + /// value returned by invocation chain + public object Invoke(object proxy, object target, Type targetType, + MethodInfo targetMethod, MethodInfo proxyMethod, object[] args, IList interceptors) + { + IMethodInvocation invocation = null; + if (UseDynamicReflection) + { + invocation = new DynamicMethodInvocation( + proxy, target, targetMethod, proxyMethod, args, targetType, interceptors); + } + else + { + invocation = new ReflectiveMethodInvocation( + proxy, target, targetMethod, proxyMethod, args, targetType, interceptors); + } + return invocation.Proceed(); + } + + /// + /// Returns a list of method interceptors + /// + /// target type + /// target method + /// list of inteceptors for the specified method + public IList GetInterceptors(Type targetType, MethodInfo method) + { + if (m_advised.Advisors.Length == 0) + { + return EmptyList; + } + else + { + return m_advised.AdvisorChainFactory.GetInterceptors(m_advised, this, method, targetType); + } + } + + #endregion + + #region IAdvised Members + + bool IAdvised.ExposeProxy + { + get { return m_advised.ExposeProxy; } + } + + IAdvisorChainFactory IAdvised.AdvisorChainFactory + { + get { return m_advised.AdvisorChainFactory; } + } + + bool IAdvised.ProxyTargetType + { + get { return m_advised.ProxyTargetType; } + } + + bool IAdvised.ProxyTargetAttributes + { + get { return m_advised.ProxyTargetAttributes; } + } + + IAdvisor[] IAdvised.Advisors + { + get { return m_advised.Advisors; } + } + + IIntroductionAdvisor[] IAdvised.Introductions + { + get { return m_advised.Introductions; } + } + + Type[] IAdvised.Interfaces + { + get { return m_advised.Interfaces; } + } + + IDictionary IAdvised.InterfaceMap + { + get { return m_advised.InterfaceMap; } + } + + bool IAdvised.IsFrozen + { + get { return m_advised.IsFrozen; } + } + + ITargetSource IAdvised.TargetSource + { + get { return m_advised.TargetSource; } + } + + bool IAdvised.IsSerializable + { + get { return m_advised.IsSerializable; } + } + + /// + /// Adds the supplied to the end (or tail) + /// of the advice (interceptor) chain. + /// + /// + /// The to be added. + /// + /// + /// + public void AddAdvice(IAdvice advice) + { + this.m_advised.AddAdvice(advice); + } + + /// + /// Adds the supplied to the supplied + /// in the advice (interceptor) chain. + /// + /// + /// The zero (0) indexed position (from the head) at which the + /// supplied is to be inserted into the + /// advice (interceptor) chain. + /// + /// + /// The to be added. + /// + /// + /// + public void AddAdvice(int position, IAdvice advice) + { + this.m_advised.AddAdvice(position, advice); + } + + bool IAdvised.IsInterfaceProxied(Type intf) + { + return m_advised.IsInterfaceProxied(intf); + } + + void IAdvised.AddAdvisors(IAdvisors advisors) + { + m_advised.AddAdvisors(advisors); + } + + void IAdvised.AddAdvisor(IAdvisor advisor) + { + m_advised.AddAdvisor(advisor); + } + + void IAdvised.AddAdvisor(int pos, IAdvisor advisor) + { + m_advised.AddAdvisor(pos, advisor); + } + + void IAdvised.AddIntroduction(IIntroductionAdvisor advisor) + { + m_advised.AddIntroduction(advisor); + } + + void IAdvised.AddIntroduction(int pos, IIntroductionAdvisor advisor) + { + m_advised.AddIntroduction(pos, advisor); + } + + int IAdvised.IndexOf(IAdvisor advisor) + { + return m_advised.IndexOf(advisor); + } + + int IAdvised.IndexOf(IIntroductionAdvisor advisor) + { + return m_advised.IndexOf(advisor); + } + + bool IAdvised.RemoveAdvisor(IAdvisor advisor) + { + return m_advised.RemoveAdvisor(advisor); + } + + void IAdvised.RemoveAdvisor(int index) + { + m_advised.RemoveAdvisor(index); + } + + bool IAdvised.RemoveAdvice(IAdvice advice) + { + return m_advised.RemoveAdvice(advice); + } + + bool IAdvised.RemoveIntroduction(IIntroductionAdvisor advisor) + { + return m_advised.RemoveIntroduction(advisor); + } + + void IAdvised.RemoveIntroduction(int index) + { + m_advised.RemoveIntroduction(index); + } + + void IAdvised.ReplaceIntroduction(int index, IIntroductionAdvisor advisor) + { + m_advised.ReplaceIntroduction(index, advisor); + } + + bool IAdvised.ReplaceAdvisor(IAdvisor a, IAdvisor b) + { + return m_advised.ReplaceAdvisor(a, b); + } + + string IAdvised.ToProxyConfigString() + { + return m_advised.ToProxyConfigString(); + } + + #endregion + + #region ITargetTypeAware implementation + + /// + /// Gets the target type behind the implementing object. + /// Ttypically a proxy configuration or an actual proxy. + /// + /// The type of the target or null if not known. + public Type TargetType + { + get { return m_targetType; } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Logging/AbstractLoggingAdvice.cs b/src/Spring/Spring.Aop/Aspects/Logging/AbstractLoggingAdvice.cs index c023034f..3537f0f4 100644 --- a/src/Spring/Spring.Aop/Aspects/Logging/AbstractLoggingAdvice.cs +++ b/src/Spring/Spring.Aop/Aspects/Logging/AbstractLoggingAdvice.cs @@ -67,6 +67,14 @@ namespace Spring.Aspects.Logging SetDefaultLogger(MethodBase.GetCurrentMethod().DeclaringType.FullName); } + /// + /// Creates a new advice instance using the given logger by default. + /// + protected AbstractLoggingAdvice(ILog defaultLogger) + { + this.defaultLogger = defaultLogger; + } + #endregion #region Properties diff --git a/src/Spring/Spring.Aop/Aspects/Logging/SimpleLoggingAdvice.cs b/src/Spring/Spring.Aop/Aspects/Logging/SimpleLoggingAdvice.cs index 22a0ddf2..7ed47472 100644 --- a/src/Spring/Spring.Aop/Aspects/Logging/SimpleLoggingAdvice.cs +++ b/src/Spring/Spring.Aop/Aspects/Logging/SimpleLoggingAdvice.cs @@ -89,8 +89,16 @@ namespace Spring.Aspects.Logging public SimpleLoggingAdvice(bool useDynamicLogger) { UseDynamicLogger = useDynamicLogger; - } - + } + + /// + /// Initializes a new instance of the class. + /// + /// the default logger to use + public SimpleLoggingAdvice(ILog defaultLogger) + : base(defaultLogger) + {} + #endregion #region Properties diff --git a/test/Spring/Spring.Aop.Tests/Aspects/Logging/SimpleLoggingAdviceTests.cs b/test/Spring/Spring.Aop.Tests/Aspects/Logging/SimpleLoggingAdviceTests.cs index 17fb7113..9266b6e9 100644 --- a/test/Spring/Spring.Aop.Tests/Aspects/Logging/SimpleLoggingAdviceTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aspects/Logging/SimpleLoggingAdviceTests.cs @@ -27,6 +27,7 @@ using AopAlliance.Intercept; using Common.Logging; using NUnit.Framework; using Rhino.Mocks; +using Spring.Aop.Framework; #endregion @@ -39,6 +40,17 @@ namespace Spring.Aspects.Logging [TestFixture] public class SimpleLoggingAdviceTests { + public interface ITestTarget + { + void DoSomething(); + } + + private class TestTarget : ITestTarget + { + public void DoSomething() + { } + } + private MockRepository mocks; [SetUp] @@ -47,6 +59,28 @@ namespace Spring.Aspects.Logging mocks = new MockRepository(); } + [Test] + public void IntegrationTest() + { + ProxyFactory pf = new ProxyFactory(new TestTarget()); + + ILog log = (ILog)mocks.CreateMock(typeof(ILog)); + SimpleLoggingAdvice loggingAdvice = new SimpleLoggingAdvice(log); + pf.AddAdvice(loggingAdvice); + + Expect.Call(log.IsTraceEnabled).Return(true).Repeat.Any(); + log.Trace("Entering DoSomething"); + log.Trace("Exiting DoSomething"); + + mocks.ReplayAll(); + + object proxy = pf.GetProxy(); + ITestTarget ptt = (ITestTarget)proxy; + ptt.DoSomething(); + + mocks.VerifyAll(); + } + [Test] public void SunnyDayLoggingCorrectly() { @@ -59,11 +93,11 @@ namespace Spring.Aspects.Logging Expect.Call(log.IsTraceEnabled).Return(true).Repeat.Any(); log.Trace("Entering ToString"); - + Expect.Call(methodInvocation.Proceed()).Return(null); log.Trace("Exiting ToString"); - + mocks.ReplayAll(); TestableSimpleLoggingAdvice loggingAdvice = new TestableSimpleLoggingAdvice(true); @@ -86,7 +120,7 @@ namespace Spring.Aspects.Logging Expect.Call(log.IsTraceEnabled).Return(false).Repeat.Any(); Expect.Call(log.IsDebugEnabled).Return(true).Repeat.Any(); log.Debug("Entering ToString"); - + Expect.Call(methodInvocation.Proceed()).Return(null); log.Debug("Exiting ToString"); @@ -151,8 +185,8 @@ namespace Spring.Aspects.Logging MethodInfo mi = typeof(Dog).GetMethod("Bark"); //two additional calls the method are to retrieve the method name on entry/exit... Expect.Call(methodInvocation.Method).Return(mi).Repeat.Any(); - int[] luckyNumbers = new int[]{1, 2, 3}; - object[] args = new object[] {"hello", luckyNumbers}; + int[] luckyNumbers = new int[] { 1, 2, 3 }; + object[] args = new object[] { "hello", luckyNumbers }; Expect.Call(methodInvocation.Arguments).Return(args); @@ -177,9 +211,9 @@ namespace Spring.Aspects.Logging mocks.VerifyAll(); } - } - - public class Dog + } + + public class Dog { public int Bark(string message, int[] luckyNumbers) {