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

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。

4

1 回答 1

2

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

希望这有帮助。

于 2013-05-30T10:35:53.997 回答