为什么Unity拦截不能捕获Exception

本文关键字:Exception 不能 Unity 为什么 | 更新日期: 2023-09-27 18:15:57

当在我的方法中抛出异常时,我遇到了Unity拦截的问题。请参考我的示例应用程序如下:

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

AuditLogging行为实现如下代码:

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

interface .cs和implementation .cs在下面:

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";
    }
}

日志文件指出异常没有写下来。我遗漏了一些东西,或者Unity拦截不能像预期的那样工作。在下面的日志文件中,它应该有[EXCEPTION],但是没有这样的内容:

----------------------------------------
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']
----------------------------------------
顺便说一句,我使用的是Enterprise Library版本5和Unity版本2.0。

为什么Unity拦截不能捕获Exception

这里的问题是yield return "ABC"。当我们应用yield return时,该方法将在惰性模式下执行,因此Exception仍然没有引发。exception只在拦截器返回MethodReturn之后引发。您更改代码如下,将看到[EXCEPTION]将被记录到文件中:

    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";
    }