PDA

View Full Version : Introduction/Mixins configuration


jebl01
04-26-2007, 12:58 PM
Are there any good examples around how to configure an introduction?

I have created my introduction and my advice, and then what? I can't find any examples on how to configure the XML...?!

Bruno Baia
04-26-2007, 01:22 PM
Hi,

An Introduction example has been added after 1.1 P3 release, donwload one of the latest nightly build (http://www.springframework.net/downloads/nightly/) and take a look to the Spring.AopQuickStart.Step6 example.

Reference documentation :
12.3.2.5. Introduction advice (http://www.springframework.net/doc-latest/reference/html/aop.html#d0e7083)

HTH,
Bruno

jebl01
04-26-2007, 03:30 PM
Thanks!
But still no config file example...

I can't get it to work, the introduction interface isn't available on the proxy?!

My config file:
<object id="LockableIntroductionAdvisor" type="NHTest.AOP_Test.LockableIntroductionAdvisor"/>
<object id="LockEnforcerAdvice" type="NHTest.AOP_Test.LockEnforcerAdvice"/>

<object id="LockableAccount" type="Spring.Aop.Framework.ProxyFactoryObject">
<property name="ProxyTargetType" value="true"/>
<property name="target">
<object id="Account"
type="NHTest.AOP_Test.Account"/>
</property>
<property name="InterceptorNames">
<list>
<value>LockEnforcerAdvice</value>
</list>
</property>
<property name="IntroductionNames">
<list>
<value>LockableIntroductionAdvisor</value>
</list>
</property>
</object>

My advisor and introduction (never mind the code, it's just a silly test):

class LockableIntroductionAdvisor : DefaultIntroductionAdvisor
{
public LockableIntroductionAdvisor() : base(new LockableIntroduction()) { }
}

class LockableIntroduction:ILockable,IAdvice
{
private bool _isLocked;
private SecurityIdentifier _sid;

#region ILockable Members

public void Lock()
{
_isLocked = true;
_sid = WindowsIdentity.GetCurrent().User;
}

public void UnLock()
{
_isLocked = false;
_sid = null;
}

public bool IsLocked
{
get
{
return _isLocked && _sid != WindowsIdentity.GetCurrent().User;
}
}

#endregion
}

My 'LockEnforcerAdvice' is doing it's job, but when trying to get hold of the ILocable interface on my proxy object, null is all I get :-(

Bruno Baia
04-26-2007, 04:18 PM
Hi,

In your advice you need to use IMethodInvocation.Proxy property to get the proxy.
IMethodInvocation.This is the target object proxied.



public object Invoke(IMethodInvocation invocation)
{
if (invocation.Proxy is ILockable)
{
[...]
}
}


- Bruno

jebl01
04-30-2007, 08:03 AM
Hi!
I have a "before advice" that looks like this:

class LockEnforcerAdvice:IMethodBeforeAdvice
{

#region IMethodBeforeAdvice Members

public void Before(System.Reflection.MethodInfo method, object[] args, object target)
{
ILockable lockable = target as ILockable;
if (lockable != null && lockable.IsLocked)
{
throw new ApplicationException("Attempted to modify locked object");
}
}

#endregion
}

Hence I have no IMethodInvocation...

Bruno Baia
04-30-2007, 01:36 PM
Hi,

2 solutions here :

* Replace you IMethodBeforeAdvice by an IMethodInterceptor, it does exactly the same thing :

public class LockEnforcerAdvice : IMethodInterceptor
{
#region IMethodInterceptor Members

public object Invoke(IMethodInvocation invocation)
{
ILockable lockable = invocation.Proxy as ILockable;
if (lockable != null && lockable.IsLocked)
{
throw new ApplicationException("Attempted to modify locked object");
}

return invocation.Proceed();
}

#endregion
}



* Keep your IMethodBeforeAdvice and use AopContext to get the current proxy instance :
Activate AopContext in ProxyFactoryObject definition :

<object id="LockableAccount" type="Spring.Aop.Framework.ProxyFactoryObject">
<property name="ExposeProxy" value="true"/>
...

And use it :

ILockable lockable = AopContext.CurrentProxy as ILockable;



HTH,
Bruno

jebl01
04-30-2007, 02:08 PM
Ok, thanks!

Wouldn't it be possible to change the IMethodBeforeAdvice interface to make this operation more intuitive?

Instead of:
void Before(MethodInfo method, object[] args, object target);

You could do something like this:
void Before(MethodInfo method, object[] args, object target, object proxy);

And then change the MethodBeforeAdviceInterceptor.Invoke implementation to something like this:
public object Invoke(IMethodInvocation invocation)
{
advice.Before(invocation.Method, invocation.Arguments, invocation.This, invocation.Proxy);

return invocation.Proceed();
}


Cheers!
/Jesper

Bruno Baia
05-01-2007, 08:45 AM
Hi,

I thought about it as Aleks added the Proxy property to the IMethodInvocation, but it will change the API. I'll ask internally...

Anyway, I'll recommend to use IMethodInterceptor. As you could see in MethodBeforeAdviceInterceptor.Invoke implementation, IMethodBeforeAdvice is just a specific IMethodInvocation.


Bruno

jebl01
05-02-2007, 08:21 AM
Bruno,
Thanks for all your help and your quick responses! I will use IMethodInterceptor as you proposed!