为什么Unity拦截器无法捕获异常?

3

当我在方法中抛出异常时,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();
    }
}

审核日志是实现以下代码的行为:

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

以下是 Interface1.cs 和 Implementation1.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']

----------------------------------------

顺便说一下,我正在使用企业库版本5和Unity版本2.0。

1个回答

2
这里的问题在于yield return "ABC"。当我们使用yield return时,方法将在延迟模式下执行,因此Exception仍未被引发。只有在拦截器返回MethodReturn后才会引发exception。如果您按以下方式更改代码,将看到[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";
    }

希望这能帮到您。

谢谢。在您的帮助下,我找到了根本原因,并理解了为什么异常没有正确记录。 - Tim Phan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接