質問

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top