polishing

This commit is contained in:
eeichinger
2009-09-27 16:48:37 +00:00
parent dcd16da294
commit 0882e83fe3
12 changed files with 170 additions and 98 deletions

View File

@@ -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" />
-->

View File

@@ -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

View File

@@ -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);
}
}
}

View File

@@ -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)
{

View File

@@ -43,7 +43,7 @@ namespace Spring.Aop.Framework.DynamicProxy
private const string PROXY_TYPE_NAME = "CompositionAopProxy";
private IAdvised advised;
private readonly IAdvised advised;
#endregion

View File

@@ -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 });
}

View File

@@ -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

View File

@@ -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" />

View File

@@ -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();
}
}

View File

@@ -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>

View File

@@ -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>();

View File

@@ -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>