polishing
This commit is contained in:
@@ -185,7 +185,7 @@ ${tool.dir} : dir for tools
|
||||
-->
|
||||
<target name="common.run-tests">
|
||||
|
||||
<call target="common.run-tests.nunit" />
|
||||
<call target="common.run-tests.ncover" />
|
||||
<!--
|
||||
<call target="common.run-tests.nunit" />
|
||||
-->
|
||||
|
||||
@@ -243,18 +243,6 @@ namespace Spring.Aop.Framework
|
||||
set
|
||||
{
|
||||
m_targetSource= (value != null) ? value : EmptyTargetSource.Empty;
|
||||
// TODO (EE):remove
|
||||
// bool initialized = !(this.m_targetSource is EmptyTargetSource);
|
||||
// this.m_targetSource = value;
|
||||
//
|
||||
// if (this.m_targetSource != null && !initialized && interfaceMap.Count == 0)
|
||||
// {
|
||||
// Type[] interfaces = ReflectionUtils.GetInterfaces(this.m_targetSource.TargetType);
|
||||
// foreach (Type intf in interfaces)
|
||||
// {
|
||||
// AddInterfaceInternal(intf);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -963,22 +951,18 @@ namespace Spring.Aop.Framework
|
||||
|
||||
#endregion
|
||||
|
||||
#region ITargetTypeAware implementation
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target type behind the implementing object.
|
||||
/// Ttypically a proxy configuration or an actual proxy.
|
||||
/// </summary>
|
||||
/// <value>The type of the target or null if not known.</value>
|
||||
public Type TargetType
|
||||
{
|
||||
get { return TargetSource.TargetType; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target type behind the implementing object.
|
||||
/// Ttypically a proxy configuration or an actual proxy.
|
||||
/// </summary>
|
||||
/// <value>The type of the target or null if not known.</value>
|
||||
public Type TargetType
|
||||
{
|
||||
get { return TargetSource.TargetType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If no explicit interfaces are specified, interfaces will be automatically determined
|
||||
/// from the target type on proxy creation. Defaults to true
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Spring.Aop.Support;
|
||||
using Spring.Aop.Target;
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
{
|
||||
/// <summary>
|
||||
/// A reusable base implementation of <see cref="IAopProxyFactory"/>, providing
|
||||
/// some useful default implementations
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
[Serializable]
|
||||
public abstract class AbstractAopProxyFactory : IAopProxyFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an <see cref="Spring.Aop.Framework.IAopProxy"/> for the
|
||||
/// supplied <paramref name="advisedSupport"/> configuration.
|
||||
/// </summary>
|
||||
/// <param name="advisedSupport">The AOP configuration.</param>
|
||||
/// <returns>An <see cref="Spring.Aop.Framework.IAopProxy"/>.</returns>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If the supplied <paramref name="advisedSupport"/> configuration is
|
||||
/// invalid.
|
||||
/// </exception>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAopProxyFactory.CreateAopProxy"/>
|
||||
public IAopProxy CreateAopProxy(AdvisedSupport advisedSupport)
|
||||
{
|
||||
if (advisedSupport == null)
|
||||
{
|
||||
throw new AopConfigException("Cannot create IAopProxy with null ProxyConfig");
|
||||
}
|
||||
if (advisedSupport.Advisors.Length == 0 && advisedSupport.TargetSource == EmptyTargetSource.Empty)
|
||||
{
|
||||
throw new AopConfigException("Cannot create IAopProxy with no advisors and no target source");
|
||||
}
|
||||
|
||||
EliminateDuplicateAdvisors(advisedSupport);
|
||||
|
||||
return DoCreateAopProxyInstance(advisedSupport);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Actually creates the proxy instance based on the supplied <see cref="AdvisedSupport"/>.
|
||||
/// </summary>
|
||||
/// <returns>the proxy instance described by <paramref name="advisedSupport"/>. Must not be <c>null</c></returns>
|
||||
protected abstract IAopProxy DoCreateAopProxyInstance(AdvisedSupport advisedSupport);
|
||||
|
||||
/// <summary>
|
||||
/// If possible, checks for advisor duplicates on the supplied <paramref name="advisedSupport"/> and
|
||||
/// eliminates them.
|
||||
/// </summary>
|
||||
protected virtual void EliminateDuplicateAdvisors(AdvisedSupport advisedSupport)
|
||||
{
|
||||
if (advisedSupport.TargetSource is SingletonTargetSource
|
||||
&& IsAopProxyType(advisedSupport.TargetSource))
|
||||
{
|
||||
IAdvised innerProxy = (IAdvised)advisedSupport.TargetSource.GetTarget();
|
||||
// eliminate duplicate advisors
|
||||
ArrayList thisAdvisors = new ArrayList(advisedSupport.Advisors);
|
||||
foreach (IAdvisor innerAdvisor in innerProxy.Advisors)
|
||||
{
|
||||
foreach (IAdvisor thisAdvisor in thisAdvisors)
|
||||
{
|
||||
if (ReferenceEquals(thisAdvisor, innerAdvisor)
|
||||
|| (thisAdvisor.GetType() == typeof(DefaultPointcutAdvisor)
|
||||
&& ((DefaultPointcutAdvisor)thisAdvisor).Equals(innerAdvisor)
|
||||
)
|
||||
)
|
||||
{
|
||||
advisedSupport.RemoveAdvisor(thisAdvisor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// elimination of duplicate introductions is not necessary
|
||||
// since they do not propagate to nested proxy anyway
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks, if the given <paramref name="targetSource"/> holds a proxy generated by this factory.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual bool IsAopProxyType(ITargetSource targetSource)
|
||||
{
|
||||
return AopUtils.IsAopProxyType(targetSource.TargetType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,11 +94,6 @@ namespace Spring.Aop.Framework.DynamicProxy
|
||||
/// <returns>true if the specified Object is equal to the current target object; otherwise, false</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
// if (ReferenceEquals(this, obj))
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
AdvisedProxy otherProxy = obj as AdvisedProxy;
|
||||
if (otherProxy != null)
|
||||
{
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Spring.Aop.Framework.DynamicProxy
|
||||
|
||||
private const string PROXY_TYPE_NAME = "CompositionAopProxy";
|
||||
|
||||
private IAdvised advised;
|
||||
private readonly IAdvised advised;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -19,11 +19,8 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using Spring.Aop.Support;
|
||||
using Spring.Proxy;
|
||||
using Spring.Aop.Target;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Aop.Framework.DynamicProxy
|
||||
@@ -51,7 +48,7 @@ namespace Spring.Aop.Framework.DynamicProxy
|
||||
/// <author>Erich Eichinger (.NET)</author>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAopProxyFactory"/>
|
||||
[Serializable]
|
||||
public class DefaultAopProxyFactory : IAopProxyFactory
|
||||
public class DefaultAopProxyFactory : AbstractAopProxyFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Force transient assemblies to be resolvable by <see cref="Assembly.Load(string)"/>.
|
||||
@@ -62,26 +59,12 @@ namespace Spring.Aop.Framework.DynamicProxy
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="Spring.Aop.Framework.IAopProxy"/> for the
|
||||
/// supplied <paramref name="advisedSupport"/> configuration.
|
||||
/// Creates an actual proxy instance based on the supplied <paramref name="advisedSupport"/>
|
||||
/// </summary>
|
||||
/// <param name="advisedSupport">The AOP configuration.</param>
|
||||
/// <returns>An <see cref="Spring.Aop.Framework.IAopProxy"/>.</returns>
|
||||
/// <exception cref="AopConfigException">
|
||||
/// If the supplied <paramref name="advisedSupport"/> configuration is
|
||||
/// invalid.
|
||||
/// </exception>
|
||||
/// <seealso cref="Spring.Aop.Framework.IAopProxyFactory.CreateAopProxy"/>
|
||||
public virtual IAopProxy CreateAopProxy(AdvisedSupport advisedSupport)
|
||||
/// <param name="advisedSupport"></param>
|
||||
/// <returns></returns>
|
||||
protected override IAopProxy DoCreateAopProxyInstance(AdvisedSupport advisedSupport)
|
||||
{
|
||||
if (advisedSupport == null)
|
||||
{
|
||||
throw new AopConfigException("Cannot create IAopProxy with null ProxyConfig");
|
||||
}
|
||||
if (advisedSupport.Advisors.Length == 0 && advisedSupport.TargetSource == EmptyTargetSource.Empty)
|
||||
{
|
||||
throw new AopConfigException("Cannot create IAopProxy with no advisors and no target source");
|
||||
}
|
||||
if (advisedSupport.ProxyType == null)
|
||||
{
|
||||
IProxyTypeBuilder typeBuilder;
|
||||
@@ -97,32 +80,6 @@ namespace Spring.Aop.Framework.DynamicProxy
|
||||
advisedSupport.ProxyType = BuildProxyType(typeBuilder);
|
||||
advisedSupport.ProxyConstructor = advisedSupport.ProxyType.GetConstructor(new Type[] { typeof(IAdvised) });
|
||||
}
|
||||
|
||||
if (advisedSupport.TargetSource is SingletonTargetSource
|
||||
&& AopUtils.IsAopProxyType(advisedSupport.TargetSource.TargetType))
|
||||
{
|
||||
IAdvised innerProxy = (IAdvised)advisedSupport.TargetSource.GetTarget();
|
||||
// eliminate duplicate advisors
|
||||
ArrayList thisAdvisors = new ArrayList(advisedSupport.Advisors);
|
||||
foreach (IAdvisor innerAdvisor in innerProxy.Advisors)
|
||||
{
|
||||
foreach (IAdvisor thisAdvisor in thisAdvisors)
|
||||
{
|
||||
if (ReferenceEquals(thisAdvisor, innerAdvisor)
|
||||
|| (thisAdvisor.GetType() == typeof(DefaultPointcutAdvisor)
|
||||
&& ((DefaultPointcutAdvisor)thisAdvisor).Equals(innerAdvisor)
|
||||
)
|
||||
)
|
||||
{
|
||||
advisedSupport.RemoveAdvisor(thisAdvisor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// elimination of duplicate introductions is not necessary
|
||||
// since they do not propagate to nested proxy anyway
|
||||
}
|
||||
|
||||
return (IAopProxy)advisedSupport.ProxyConstructor.Invoke(new object[] { advisedSupport });
|
||||
}
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ namespace Spring.Aop.Target
|
||||
[Serializable]
|
||||
public sealed class SingletonTargetSource : ITargetSource
|
||||
{
|
||||
private object target;
|
||||
private Type targetType;
|
||||
private readonly object target;
|
||||
private readonly Type targetType;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
|
||||
@@ -141,6 +141,7 @@
|
||||
<Compile Include="Aop\Framework\AutoProxy\PointcutFilteringAutoProxyCreator.cs" />
|
||||
<Compile Include="Aop\Framework\AutoProxy\TypeNameAutoProxyCreator.cs" />
|
||||
<Compile Include="Aop\Framework\DynamicMethodInvocation.cs" />
|
||||
<Compile Include="Aop\Framework\DynamicProxy\AbstractAopProxyFactory.cs" />
|
||||
<Compile Include="Aop\Framework\DynamicProxy\CachedAopProxyFactory.cs" />
|
||||
<Compile Include="Aop\Framework\DynamicProxy\DefaultAopProxyFactory.cs" />
|
||||
<Compile Include="Aop\Framework\DynamicProxy\InheritanceAopProxyTypeBuilder.cs" />
|
||||
|
||||
@@ -27,6 +27,7 @@ using Spring.Expressions.Parser;
|
||||
using Spring.Expressions.Parser.antlr;
|
||||
using Spring.Expressions.Parser.antlr.collections;
|
||||
using Spring.Core;
|
||||
using Spring.Reflection.Dynamic;
|
||||
using Spring.Util;
|
||||
using StringUtils = Spring.Util.StringUtils;
|
||||
|
||||
@@ -63,14 +64,57 @@ namespace Spring.Expressions
|
||||
internal static readonly string CurrentObjectFactory = RESERVEDPREFIX + "CurrentObjectFactory";
|
||||
}
|
||||
|
||||
private class ASTNodeCreator : Parser.antlr.ASTNodeCreator
|
||||
{
|
||||
private readonly SafeConstructor ctor;
|
||||
private readonly string name;
|
||||
|
||||
public ASTNodeCreator(ConstructorInfo ctor)
|
||||
{
|
||||
this.ctor = new SafeConstructor(ctor);
|
||||
this.name = ctor.DeclaringType.FullName;
|
||||
}
|
||||
|
||||
public override AST Create()
|
||||
{
|
||||
return (AST) ctor.Invoke(new object[0]);
|
||||
}
|
||||
|
||||
public override string ASTNodeTypeName
|
||||
{
|
||||
get { return name; }
|
||||
}
|
||||
}
|
||||
|
||||
private class SpringASTFactory : ASTFactory
|
||||
{
|
||||
public SpringASTFactory( Type t )
|
||||
: base( t.FullName )
|
||||
private static readonly Type BASENODE_TYPE;
|
||||
private static readonly Hashtable Typename2Creator;
|
||||
|
||||
static SpringASTFactory()
|
||||
{
|
||||
base.defaultASTNodeTypeObject_ = t;
|
||||
base.typename2creator_ = new Hashtable( 32, 0.3f );
|
||||
base.typename2creator_[t.FullName] = SpringAST.Creator;
|
||||
BASENODE_TYPE = typeof (SpringAST);
|
||||
|
||||
Typename2Creator = new Hashtable();
|
||||
foreach (Type type in typeof(SpringASTFactory).Assembly.GetTypes())
|
||||
{
|
||||
if (BASENODE_TYPE.IsAssignableFrom(type))
|
||||
{
|
||||
ConstructorInfo ctor = type.GetConstructor(new Type[0]);
|
||||
if (ctor != null)
|
||||
{
|
||||
ASTNodeCreator creator = new ASTNodeCreator(ctor);
|
||||
Typename2Creator[creator.ASTNodeTypeName] = creator;
|
||||
}
|
||||
}
|
||||
}
|
||||
Typename2Creator[BASENODE_TYPE.FullName] = SpringAST.Creator;
|
||||
}
|
||||
|
||||
public SpringASTFactory() : base(BASENODE_TYPE)
|
||||
{
|
||||
base.defaultASTNodeTypeObject_ = BASENODE_TYPE;
|
||||
base.typename2creator_ = Typename2Creator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +123,7 @@ namespace Spring.Expressions
|
||||
public SpringExpressionParser( TokenStream lexer )
|
||||
: base( lexer )
|
||||
{
|
||||
base.astFactory = new SpringASTFactory( typeof( SpringAST ) );
|
||||
base.astFactory = new SpringASTFactory();
|
||||
base.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,11 +266,9 @@ namespace Spring.Proxy
|
||||
/// Calls target method directly.
|
||||
/// </summary>
|
||||
/// <param name="il">The IL generator to use.</param>
|
||||
/// <param name="interfaceMethod">
|
||||
/// The interface definition of the method, if applicable.
|
||||
/// </param>
|
||||
/// <param name="targetMethod">The method to invoke.</param>
|
||||
protected virtual void CallDirectTargetMethod(
|
||||
ILGenerator il, MethodInfo interfaceMethod)
|
||||
ILGenerator il, MethodInfo targetMethod)
|
||||
{
|
||||
// setup target object for call
|
||||
PushTarget(il);
|
||||
@@ -279,21 +277,21 @@ namespace Spring.Proxy
|
||||
LocalBuilder targetRef = il.DeclareLocal(typeof(object));
|
||||
il.Emit(OpCodes.Stloc, targetRef);
|
||||
|
||||
CallAssertUnderstands(il, interfaceMethod, targetRef, "target");
|
||||
CallAssertUnderstands(il, targetMethod, targetRef, "target");
|
||||
|
||||
// setup target and cast to type method is on
|
||||
il.Emit(OpCodes.Ldloc, targetRef);
|
||||
il.Emit(OpCodes.Castclass, interfaceMethod.DeclaringType);
|
||||
il.Emit(OpCodes.Castclass, targetMethod.DeclaringType);
|
||||
|
||||
// setup parameters for call
|
||||
ParameterInfo[] paramArray = interfaceMethod.GetParameters();
|
||||
ParameterInfo[] paramArray = targetMethod.GetParameters();
|
||||
for (int i = 0; i < paramArray.Length; i++)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_S, i + 1);
|
||||
}
|
||||
|
||||
// call method
|
||||
il.EmitCall(OpCodes.Callvirt, interfaceMethod, null);
|
||||
il.EmitCall(OpCodes.Callvirt, targetMethod, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -847,6 +847,8 @@ namespace Spring.Aop.Framework.DynamicProxy
|
||||
CreateProxy(advised) as AbstractProxyTypeBuilderTests.InterfaceWithGenericMethod;
|
||||
Assert.IsNotNull(proxy);
|
||||
|
||||
DynamicProxyManager.SaveAssembly();
|
||||
|
||||
proxy.PolymorphicMethod<int>();
|
||||
proxy.PolymorphicMethod<string>();
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>TRACE;DEBUG;NET_2_0;DEBUG_DYNAMIC</DefineConstants>
|
||||
<DocumentationFile>Spring.Aop.Tests.xml</DocumentationFile>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
|
||||
Reference in New Issue
Block a user