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.Ceq);
|
||||||
il.Emit(OpCodes.Brtrue_S, noException);
|
il.Emit(OpCodes.Brtrue_S, noException);
|
||||||
il.Emit(OpCodes.Ldloc, ex);
|
il.Emit(OpCodes.Ldloc, ex);
|
||||||
|
|
||||||
|
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.Emit(OpCodes.Throw);
|
||||||
|
}
|
||||||
|
|
||||||
il.MarkLabel(noException);
|
il.MarkLabel(noException);
|
||||||
|
|
||||||
|
|
|
@ -416,7 +416,17 @@ namespace Unity.Interception.Interceptors.TypeInterceptors.VirtualMethodIntercep
|
||||||
il.Emit(OpCodes.Ceq);
|
il.Emit(OpCodes.Ceq);
|
||||||
il.Emit(OpCodes.Brtrue_S, noException);
|
il.Emit(OpCodes.Brtrue_S, noException);
|
||||||
il.Emit(OpCodes.Ldloc, ex);
|
il.Emit(OpCodes.Ldloc, ex);
|
||||||
|
|
||||||
|
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.Emit(OpCodes.Throw);
|
||||||
|
}
|
||||||
|
|
||||||
il.MarkLabel(noException);
|
il.MarkLabel(noException);
|
||||||
|
|
||||||
|
|
|
@ -149,5 +149,21 @@ namespace Unity.Interception.Utilities
|
||||||
attributes.AddRange(GetAttributes<TAttribute>(member, inherits));
|
attributes.AddRange(GetAttributes<TAttribute>(member, inherits));
|
||||||
return attributes.ToArray();
|
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.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using Microsoft.Practices.Unity.InterceptionExtension.Tests.MatchingRules;
|
using Microsoft.Practices.Unity.InterceptionExtension.Tests.MatchingRules;
|
||||||
using Microsoft.Practices.Unity.InterceptionExtension.Tests.ObjectsUnderTest;
|
using Microsoft.Practices.Unity.InterceptionExtension.Tests.ObjectsUnderTest;
|
||||||
using Microsoft.Practices.Unity.TestSupport;
|
using Microsoft.Practices.Unity.TestSupport;
|
||||||
|
@ -1669,5 +1670,63 @@ namespace Microsoft.Practices.Unity.InterceptionExtension.Tests.InterfaceInterce
|
||||||
return 0;
|
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.Interceptors.TypeInterceptors.VirtualMethodInterception;
|
||||||
using Unity.Interception.PolicyInjection;
|
using Unity.Interception.PolicyInjection;
|
||||||
using Unity.Interception.PolicyInjection.Pipeline;
|
using Unity.Interception.PolicyInjection.Pipeline;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Microsoft.Practices.Unity.InterceptionExtension.Tests.VirtualMethodInterceptorTests
|
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
|
public partial class DerivedTypeCreator
|
||||||
|
|
Загрузка…
Ссылка в новой задаче