c# - 为什么Unity拦截抓不到Exception?

标签 c# .net unity-container aop unity-interception

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

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。

最佳答案

这里的问题是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";
    }

希望这对您有所帮助。

关于c# - 为什么Unity拦截抓不到Exception?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16832499/

相关文章:

c# - 让数据库连接保持打开状态?

c# - 导致 IndexOutOfBounds 异常的线程

c# - 覆盖 getter 和 setter 的替代方法

c# - 隐式转换数组

.net - WPF MVVM 从 ViewModel 触发事件的正确方法

c# - 最近用户查询

c# - 在 .NET 中将 int 转换为 byte[4]

c# - 部署具有 MSI 的容器实例并且部署到该实例的容器无法读取 keyvault secret

c# - Unity,使用语句和 PerRequestLifetimeManager

dependency-injection - 将 Unity Hook 到 Web API 过滤器属性中