I got an issue with Unity interception when throw an Exception in my method. Please reference from my sample application as below:
class Program
{
static void Main(string[] args)
{
var container = new UnityContainer();
container.RegisterType<IInterface1, Implementation1>();
container.RegisterType<ICallHandler, AuditLoggingCallHandler>();
container.RegisterInstance(typeof(IUnityContainer), container);
container.AddNewExtension<Interception>();
container.Configure<Interception>()
.SetInterceptorFor<IInterface1>(new InterfaceInterceptor());
var service = container.Resolve<IInterface1>();
service.Method1("xyz");
Console.ReadLine();
}
}
The AuditLogging behavior implement following code below:
public class AuditLoggingAttribute : HandlerAttribute
{
public int RequestId { get; set; }
public override ICallHandler CreateHandler(IUnityContainer container)
{
return container.Resolve<ICallHandler>();
}
}
public class AuditLoggingCallHandler : ICallHandler
{
public IMethodReturn Invoke(IMethodInvocation input,
GetNextHandlerDelegate getNext)
{
LogEntry logEntry = new LogEntry();
logEntry.Message = "[BEGIN] " + input.MethodBase.Name + "()";
Logger.Write(logEntry);
IMethodReturn result = getNext()(input, getNext);
if (result.Exception != null)
{
logEntry = new LogEntry();
logEntry.Message = " [EXCEPTION] " + input.MethodBase.Name
+ "." + input.MethodBase.Name
+ "() ";
logEntry.ExtendedProperties
.Add("Exception Message", result.Exception.Message);
logEntry.ExtendedProperties
.Add("Exception StackTrace", result.Exception.StackTrace);
Logger.Write(logEntry);
}
logEntry = new LogEntry();
logEntry.Message = " [FINISH] " + input.MethodBase.Name + "()";
if (result.ReturnValue != null)
{
logEntry
.ExtendedProperties
.Add("Return value", result.ReturnValue.ToString());
}
Logger.Write(logEntry);
return result;
}
public int Order { get; set; }
}
And the Interface1.cs and Implementation1.cs are below:
public interface IInterface1
{
[AuditLogging]
IEnumerable<string> Method1(string name);
}
public class Implementation1 : IInterface1
{
public IEnumerable<string> Method1(string name)
{
if (name.Equals("xyz"))
{
throw new Exception("xyz are not allow");
}
yield return "ABC";
}
}
The logging file point out the Exception does not write down.There is some thing I am missing or the Unity interception cannot working as expected.
Here the log file below, it should have [EXCEPTION]
but there is nothing like that:
----------------------------------------
Timestamp: 5/30/2013 9:29:07 AM
Message: [BEGIN] Method1()
Category: General
Priority: -1
EventId: 0
Severity: Information
Title:
Machine: XXXY
App Domain: ConsoleApplication10.vshost.exe
ProcessId: 8228
Thread Name:
Win32 ThreadId:1280
Extended Properties: Parameter values - [(String) name = 'xyz']
----------------------------------------
BTW, I using the Enterprise Library version 5 and Unity version 2.0.
The issue at here is yield return "ABC"
. When we apply yield return
the method will be executed under lazy mode so the Exception
still not raised. The exception
only raise after the MethodReturn
return by interceptor. You change the code as below will see [EXCEPTION]
will be logged into the file:
public IEnumerable<string> Method1(string name)
{
if (name.Equals("xyz"))
{
throw new Exception("xyz are not allow");
}
var list = new List<string>();
list.Add("ABC");
return list;
//yield return "ABC";
}
Hope this help.