Renewing bugfix in PR #92
This commit is contained in:
Родитель
e5a27078a2
Коммит
ce03d98592
|
@ -414,7 +414,17 @@ namespace Unity.Interception.Interceptors.InstanceInterceptors.InterfaceIntercep
|
|||
il.Emit(OpCodes.Ceq);
|
||||
il.Emit(OpCodes.Brtrue_S, noException);
|
||||
il.Emit(OpCodes.Ldloc, ex);
|
||||
il.Emit(OpCodes.Throw);
|
||||
|
||||
if (ReflectionHelper.ExceptionDispatchInfoCaptureMethod != null
|
||||
&& ReflectionHelper.ExceptionDispatchInfoThrowMethod != null)
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ReflectionHelper.ExceptionDispatchInfoCaptureMethod, null);
|
||||
il.EmitCall(OpCodes.Callvirt, ReflectionHelper.ExceptionDispatchInfoThrowMethod, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
il.Emit(OpCodes.Throw);
|
||||
}
|
||||
|
||||
il.MarkLabel(noException);
|
||||
|
||||
|
|
|
@ -416,7 +416,17 @@ namespace Unity.Interception.Interceptors.TypeInterceptors.VirtualMethodIntercep
|
|||
il.Emit(OpCodes.Ceq);
|
||||
il.Emit(OpCodes.Brtrue_S, noException);
|
||||
il.Emit(OpCodes.Ldloc, ex);
|
||||
il.Emit(OpCodes.Throw);
|
||||
|
||||
if (ReflectionHelper.ExceptionDispatchInfoCaptureMethod != null
|
||||
&& ReflectionHelper.ExceptionDispatchInfoThrowMethod != null)
|
||||
{
|
||||
il.EmitCall(OpCodes.Call, ReflectionHelper.ExceptionDispatchInfoCaptureMethod, null);
|
||||
il.EmitCall(OpCodes.Callvirt, ReflectionHelper.ExceptionDispatchInfoThrowMethod, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
il.Emit(OpCodes.Throw);
|
||||
}
|
||||
|
||||
il.MarkLabel(noException);
|
||||
|
||||
|
|
|
@ -149,5 +149,21 @@ namespace Unity.Interception.Utilities
|
|||
attributes.AddRange(GetAttributes<TAttribute>(member, inherits));
|
||||
return attributes.ToArray();
|
||||
}
|
||||
|
||||
public static readonly MethodInfo ExceptionDispatchInfoCaptureMethod;
|
||||
|
||||
public static readonly MethodInfo ExceptionDispatchInfoThrowMethod;
|
||||
|
||||
static ReflectionHelper()
|
||||
{
|
||||
Assembly mscorlib = typeof(int).Assembly;
|
||||
ExceptionDispatchInfoCaptureMethod = mscorlib
|
||||
?.GetType("System.Runtime.ExceptionServices.ExceptionDispatchInfo")
|
||||
?.GetMethod("Capture", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(Exception) }, null);
|
||||
|
||||
ExceptionDispatchInfoThrowMethod = mscorlib
|
||||
?.GetType("System.Runtime.ExceptionServices.ExceptionDispatchInfo")
|
||||
?.GetMethod("Throw", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { }, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Practices.Unity.InterceptionExtension.Tests.MatchingRules;
|
||||
using Microsoft.Practices.Unity.InterceptionExtension.Tests.ObjectsUnderTest;
|
||||
using Microsoft.Practices.Unity.TestSupport;
|
||||
|
@ -1669,5 +1670,63 @@ namespace Microsoft.Practices.Unity.InterceptionExtension.Tests.InterfaceInterce
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InterceptorCorrectlyRethrowsException()
|
||||
{
|
||||
IUnityContainer container = new UnityContainer()
|
||||
.AddNewExtension<Interception>()
|
||||
.RegisterType(typeof(IFoo), typeof(Foo))
|
||||
.Configure<Interception>()
|
||||
.SetInterceptorFor(typeof(IFoo), new InterfaceInterceptor())
|
||||
.AddPolicy("AlwaysMatches")
|
||||
.AddMatchingRule<AlwaysMatchingRule>()
|
||||
.AddCallHandler<CallCountHandler>("callCount", new ContainerControlledLifetimeManager())
|
||||
.Interception
|
||||
.Container;
|
||||
|
||||
IFoo myFoo = container.Resolve<IFoo>();
|
||||
|
||||
try
|
||||
{
|
||||
myFoo.DoSomething();
|
||||
Assert.Fail("Should have thrown");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CallCountHandler handler = (CallCountHandler)(container.Resolve<ICallHandler>("callCount"));
|
||||
Assert.AreEqual(1, handler.CallCount);
|
||||
Assert.IsInstanceOfType(ex, typeof(FooCrashedException));
|
||||
|
||||
var stackTrace = ex.StackTrace.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
|
||||
Assert.IsTrue(stackTrace[0].Contains("DoSomethingLocal"), "stack trace is not full");
|
||||
}
|
||||
}
|
||||
|
||||
public interface IFoo
|
||||
{
|
||||
void DoSomething();
|
||||
}
|
||||
|
||||
public class Foo : IFoo
|
||||
{
|
||||
public virtual void DoSomething()
|
||||
{
|
||||
DoSomethingLocal();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
protected void DoSomethingLocal()
|
||||
{
|
||||
throw new FooCrashedException("oops");
|
||||
}
|
||||
}
|
||||
|
||||
public class FooCrashedException : Exception
|
||||
{
|
||||
public FooCrashedException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ using Unity.Interception.Interceptors;
|
|||
using Unity.Interception.Interceptors.TypeInterceptors.VirtualMethodInterception;
|
||||
using Unity.Interception.PolicyInjection;
|
||||
using Unity.Interception.PolicyInjection.Pipeline;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Microsoft.Practices.Unity.InterceptionExtension.Tests.VirtualMethodInterceptorTests
|
||||
{
|
||||
|
@ -866,6 +867,64 @@ namespace Microsoft.Practices.Unity.InterceptionExtension.Tests.VirtualMethodInt
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InterceptorCorrectlyRethrowsException()
|
||||
{
|
||||
IUnityContainer container = new UnityContainer()
|
||||
.AddNewExtension<Interception>()
|
||||
.RegisterType(typeof(IFoo), typeof(Foo))
|
||||
.Configure<Interception>()
|
||||
.SetInterceptorFor(typeof(Foo), new VirtualMethodInterceptor())
|
||||
.AddPolicy("AlwaysMatches")
|
||||
.AddMatchingRule<AlwaysMatchingRule>()
|
||||
.AddCallHandler<CallCountHandler>("callCount", new ContainerControlledLifetimeManager())
|
||||
.Interception
|
||||
.Container;
|
||||
|
||||
IFoo myFoo = container.Resolve<IFoo>();
|
||||
|
||||
try
|
||||
{
|
||||
myFoo.DoSomething();
|
||||
Assert.Fail("Should have thrown");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CallCountHandler handler = (CallCountHandler)(container.Resolve<ICallHandler>("callCount"));
|
||||
Assert.AreEqual(1, handler.CallCount);
|
||||
Assert.IsInstanceOfType(ex, typeof(FooCrashedException));
|
||||
|
||||
var stackTrace = ex.StackTrace.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
|
||||
Assert.IsTrue(stackTrace[0].Contains("DoSomethingLocal"), "stack trace is not full");
|
||||
}
|
||||
}
|
||||
|
||||
public interface IFoo
|
||||
{
|
||||
void DoSomething();
|
||||
}
|
||||
|
||||
public class Foo : IFoo
|
||||
{
|
||||
public virtual void DoSomething()
|
||||
{
|
||||
DoSomethingLocal();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
protected void DoSomethingLocal()
|
||||
{
|
||||
throw new FooCrashedException("oops");
|
||||
}
|
||||
}
|
||||
|
||||
public class FooCrashedException : Exception
|
||||
{
|
||||
public FooCrashedException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class DerivedTypeCreator
|
||||
|
|
Загрузка…
Ссылка в новой задаче