I start learning Spring.NET framework and I am very confusing with behavior of proxy, auto-proxy and exception handling.
for example I defined simple business object and from this object I will throw custom exception.
namespace Aspect.Managers
{
public interface IDbCustomerManager
{
Customer GetCustomerById(long id);
}
public class DbCustomerManager:IDbCustomerManager
{
public Customer GetCustomerById(long id)
{
throw new DbException(string.Format("Problem load customer with Id: {0}",id));
}
}
}
Second I defined Advice for handling with exception.
public class LogExThrowsAdvice:IThrowsAdvice
{
public void AfterThrowing(MethodInfo method, Object[] args,
Object target, DbException exception)
{
Console.WriteLine(exception.Message);
}
}
And last I join togheter business object and advice with proxy.
In app.confing
Advice:
<object id="theLogExThrowsAdvice"
type="Aspect.LogExThrowsAdvice, Log4NetInSpringNet"/>
Auto-Proxy
<object id="theProxyCreator"
type="Spring.Aop.Framework.AutoProxy.TypeNameAutoProxyCreator, Spring.Aop">
<property name="TypeNames" value="Aspect.Managers.DbCustomerManager*"/>
<property name="InterceptorNames">
<list>
<value>theLogExThrowsAdvice</value>
</list>
</property>
</object>
And test it:
var springContext = ContextRegistry.GetContext();
var dbMgr = (IDbCustomerManager)springContext["theDbCustomerManager"];
dbMgr.GetCustomerById(1);
Exception is throwed, method AfterThrowing from LogExThrowsAdvice is not calling.
I try changed type of advice for type BeforeAdvice.
public class DbAccessAdvice:IMethodBeforeAdvice
{
#region Implementation of IMethodBeforeAdvice
public void Before(MethodInfo method, object[] args, object target)
{
Console.WriteLine("You try access to DB");
}
#endregion
}
and in app.config:
<object id="theDbAccessAdvice"
type="Aspect.DbAccessAdvice, Log4NetInSpringNet"/>
<object id="theProxyCreator"
type="Spring.Aop.Framework.AutoProxy.TypeNameAutoProxyCreator, Spring.Aop">
<property name="TypeNames" value="Aspect.Managers.DbCustomerManager*"/>
<property name="InterceptorNames">
<list>
<value>theDbAccessAdvice</value>
<value>theLogExThrowsAdvice</value>
</list>
</property>
</object>
BeforeAdvice is fire but ThrowsAdvice no. Why?
I tried change auto proxy for proxy object factory and tried proxying interfaces IDbCustomerManager.
<object id="theProxy"
type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
<property name="ProxyInterfaces" value="Aspect.Managers.IDbCustomerManager"/>
<property name="Target">
<object type="Aspect.Managers.DbCustomerManager">
</object>
</property>
<property name="InterceptorNames">
<list>
<value>theDbAccessAdvice</value>
<value>theLogAdvice</value>
</list>
</property>
</object>
var springContext = ContextRegistry.GetContext();
var dbMgr = (IDbCustomerManager)springContext["theProxy"];
dbMgr.GetCustomerById(1);
Before advice is fired but throws advice are not? why? Only exception is throwed.
For me is magic how it really work.
I tried used Advisors instead advices:
<!--Advisor-->
<object id="theDbAccessAdvisor"
type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop">
<property name="Pattern" value="Aspect*"/>
<property name="Advice" ref="theDbAccessAdvice"/>
</object>
<object id="theLogAdvisor"
type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop">
<property name="Pattern" value="Aspect*"/>
<property name="Advice" ref="theLogAdvice"/>
</object>
But same result before advice is fired but throws advice not.
I tried use also ExceptionHandleAdvice aspect from Spring.NET same exception is throwed but advice not.
<object id="exAdvice"
type="Spring.Aspects.Exceptions.ExceptionHandlerAdvice, Spring.Aop">
<property name="ExceptionHandlers">
<list>
<value>on exception name DbException swallow</value>
</list>
</property>
</object>
This project is for me magic I upload all VS project here:
http://hotfile.com/dl/135485464/93558e0/Log4Net.7z.html
Here is stackTrace of exception:
at Aspect.Managers.DbCustomerManager.GetCustomerById(Int64 id) in E:\C# PROJECTS\STUDY\SPRING.NET\Study.Spring.Net\Aspects\Logging\Log4Net\Managers\DbCustomerManager.cs:line 20 at _dynamic_Aspect.Managers.DbCustomerManager.GetCustomerById(Object , Object[] ) at Spring.Reflection.Dynamic.SafeMethod.Invoke(Object target, Object[] arguments) at Spring.Aop.Framework.DynamicMethodInvocation.InvokeJoinpoint() at Spring.Aop.Framework.AbstractMethodInvocation.Proceed() at Spring.Aspects.Exceptions.ExceptionHandlerAdvice.Invoke(IMethodInvocation invocation)
Also if I try catch exception something like this:
try
{
var springContext = ContextRegistry.GetContext();
var dbMgr = (IDbCustomerManager)springContext["theDbCustomerManager"];
dbMgr.GetCustomerById(1);
}
catch (Exception ex)
{
Console.WriteLine("{0}\n{1}", ex.GetType(), ex.Message);
}
It is not possible..system show message is unhandled exception....