diff --git a/src/AspectCore.Core/Utils/ProxyGeneratorUtils.cs b/src/AspectCore.Core/Utils/ProxyGeneratorUtils.cs
index 5b518209..80a8d74c 100644
--- a/src/AspectCore.Core/Utils/ProxyGeneratorUtils.cs
+++ b/src/AspectCore.Core/Utils/ProxyGeneratorUtils.cs
@@ -569,12 +569,14 @@ void EmitMethodBody()
{
if (parameters[i].IsByRef)
{
+ Type byrefToType = parameters[i].GetElementType();
+
ilGen.EmitLoadArg(i + 1);
ilGen.Emit(OpCodes.Ldloc, argsLocal);
ilGen.EmitInt(i);
ilGen.Emit(OpCodes.Ldelem_Ref);
ilGen.EmitConvertFromObject(parameters[i].GetElementType());
- ilGen.EmitStRef(parameters[i]);
+ ilGen.EmitStRef(byrefToType);
}
}
if (!method.IsVoid())
@@ -622,12 +624,14 @@ void EmitProxyMethodBody()
{
if (parameterTypes[i].IsByRef)
{
+ Type byrefToType = parameterTypes[i].GetElementType();
+
ilGen.EmitLoadArg(i + 1);
ilGen.Emit(OpCodes.Ldloc, parameters);
ilGen.EmitInt(i);
ilGen.Emit(OpCodes.Ldelem_Ref);
- ilGen.EmitConvertFromObject(parameterTypes[i].GetElementType());
- ilGen.EmitStRef(parameterTypes[i]);
+ ilGen.EmitConvertFromObject(byrefToType);
+ ilGen.EmitStRef(byrefToType);
}
}
}
@@ -928,7 +932,7 @@ private static void CopyDefaultValueConstant(ParameterInfo from, ParameterBuilde
// If this bug is present, it is caused by a `null` default value:
defaultValue = null;
}
- catch (FormatException) when (from.ParameterType.GetTypeInfo().IsEnum)
+ catch (FormatException) when (from.ParameterType.IsEnum)
{
// This catch clause guards against a CLR bug that makes it impossible to query
// the default value of a (closed generic) enum parameter. For the CoreCLR, see
@@ -973,7 +977,7 @@ private static void CopyDefaultValueConstant(ParameterInfo from, ParameterBuilde
// would "produce" a default value of `Missing.Value` in this situation).
return;
}
- else if (parameterType.GetTypeInfo().IsValueType)
+ else if (parameterType.IsValueType)
{
// This guards against a CLR bug that prohibits replicating `null` default
// values for non-nullable value types (which, despite the apparent type
@@ -989,7 +993,7 @@ private static void CopyDefaultValueConstant(ParameterInfo from, ParameterBuilde
else if (isNullableType)
{
parameterNonNullableType = from.ParameterType.GetGenericArguments()[0];
- if (parameterNonNullableType.GetTypeInfo().IsEnum || parameterNonNullableType.IsInstanceOfType(defaultValue))
+ if (parameterNonNullableType.IsEnum || parameterNonNullableType.IsInstanceOfType(defaultValue))
{
// This guards against two bugs:
//
diff --git a/src/AspectCore.Extensions.Reflection/Emit/ILGeneratorExtensions.cs b/src/AspectCore.Extensions.Reflection/Emit/ILGeneratorExtensions.cs
index a8171c14..89f65472 100644
--- a/src/AspectCore.Extensions.Reflection/Emit/ILGeneratorExtensions.cs
+++ b/src/AspectCore.Extensions.Reflection/Emit/ILGeneratorExtensions.cs
@@ -210,25 +210,17 @@ public static void EmitCastToType(this ILGenerator ilGenerator, TypeInfo typeFro
{
throw new ArgumentNullException(nameof(ilGenerator));
}
- if (!typeFrom.IsValueType && typeTo.IsValueType)
+ if (typeFrom.IsValueType)
{
- ilGenerator.Emit(OpCodes.Unbox_Any, typeTo.AsType());
- }
- else if (typeFrom.IsValueType && !typeTo.IsValueType)
- {
- ilGenerator.Emit(OpCodes.Box, typeFrom.AsType());
- if (typeTo.AsType() != typeof(object))
+ ilGenerator.Emit(OpCodes.Box, typeFrom);
+ if (typeTo != typeof(object))
{
- ilGenerator.Emit(OpCodes.Castclass, typeTo.AsType());
+ ilGenerator.Emit(OpCodes.Castclass, typeTo);
}
}
- else if (!typeFrom.IsValueType && !typeTo.IsValueType)
- {
- ilGenerator.Emit(OpCodes.Castclass, typeTo.AsType());
- }
else
{
- throw new InvalidCastException($"Caanot cast {typeFrom} to {typeTo}.");
+ ilGenerator.Emit(typeTo.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, typeTo);
}
}
@@ -693,49 +685,48 @@ public static void EmitLdRef(this ILGenerator ilGenerator, Type type)
{
throw new ArgumentNullException(nameof(type));
}
- if (type == typeof(short))
- {
- ilGenerator.Emit(OpCodes.Ldind_I1);
- }
- else if (type == typeof(Int16))
- {
- ilGenerator.Emit(OpCodes.Ldind_I2);
- }
- else if (type == typeof(Int32))
- {
- ilGenerator.Emit(OpCodes.Ldind_I4);
- }
- else if (type == typeof(Int64))
- {
- ilGenerator.Emit(OpCodes.Ldind_I8);
- }
- else if (type == typeof(float))
- {
- ilGenerator.Emit(OpCodes.Ldind_R4);
- }
- else if (type == typeof(double))
- {
- ilGenerator.Emit(OpCodes.Ldind_R8);
- }
- else if (type == typeof(ushort))
- {
- ilGenerator.Emit(OpCodes.Ldind_U1);
- }
- else if (type == typeof(UInt16))
- {
- ilGenerator.Emit(OpCodes.Ldind_U2);
- }
- else if (type == typeof(UInt32))
- {
- ilGenerator.Emit(OpCodes.Ldind_U4);
- }
- else if (type.GetTypeInfo().IsValueType)
- {
- ilGenerator.Emit(OpCodes.Ldobj);
- }
- else
+ switch (Type.GetTypeCode(type))
{
- ilGenerator.Emit(OpCodes.Ldind_Ref);
+ case TypeCode.SByte:
+ ilGenerator.Emit(OpCodes.Ldind_I1);
+ break;
+ case TypeCode.Boolean:
+ case TypeCode.Byte:
+ ilGenerator.Emit(OpCodes.Ldind_U1);
+ break;
+ case TypeCode.Int16:
+ ilGenerator.Emit(OpCodes.Ldind_I2);
+ break;
+ case TypeCode.Char:
+ case TypeCode.UInt16:
+ ilGenerator.Emit(OpCodes.Ldind_U2);
+ break;
+ case TypeCode.Int32:
+ ilGenerator.Emit(OpCodes.Ldind_I4);
+ break;
+ case TypeCode.UInt32:
+ ilGenerator.Emit(OpCodes.Ldind_U4);
+ break;
+ case TypeCode.Int64:
+ case TypeCode.UInt64:
+ ilGenerator.Emit(OpCodes.Ldind_I8);
+ break;
+ case TypeCode.Single:
+ ilGenerator.Emit(OpCodes.Ldind_R4);
+ break;
+ case TypeCode.Double:
+ ilGenerator.Emit(OpCodes.Ldind_R8);
+ break;
+ default:
+ if (type.IsValueType)
+ {
+ ilGenerator.Emit(OpCodes.Ldobj, type);
+ }
+ else
+ {
+ ilGenerator.Emit(OpCodes.Ldind_Ref);
+ }
+ break;
}
}
@@ -749,37 +740,42 @@ public static void EmitStRef(this ILGenerator ilGenerator, Type type)
{
throw new ArgumentNullException(nameof(type));
}
- if (type == typeof(short))
- {
- ilGenerator.Emit(OpCodes.Stind_I1);
- }
- else if (type == typeof(Int16))
- {
- ilGenerator.Emit(OpCodes.Stind_I2);
- }
- else if (type == typeof(Int32))
- {
- ilGenerator.Emit(OpCodes.Stind_I4);
- }
- else if (type == typeof(Int64))
- {
- ilGenerator.Emit(OpCodes.Stind_I8);
- }
- else if (type == typeof(float))
- {
- ilGenerator.Emit(OpCodes.Stind_R4);
- }
- else if (type == typeof(double))
- {
- ilGenerator.Emit(OpCodes.Stind_R8);
- }
- else if (type.GetTypeInfo().IsValueType)
- {
- ilGenerator.Emit(OpCodes.Stobj);
- }
- else
+ switch (Type.GetTypeCode(type))
{
- ilGenerator.Emit(OpCodes.Stind_Ref);
+ case TypeCode.Boolean:
+ case TypeCode.Byte:
+ case TypeCode.SByte:
+ ilGenerator.Emit(OpCodes.Stind_I1);
+ break;
+ case TypeCode.Char:
+ case TypeCode.Int16:
+ case TypeCode.UInt16:
+ ilGenerator.Emit(OpCodes.Stind_I2);
+ break;
+ case TypeCode.Int32:
+ case TypeCode.UInt32:
+ ilGenerator.Emit(OpCodes.Stind_I4);
+ break;
+ case TypeCode.Int64:
+ case TypeCode.UInt64:
+ ilGenerator.Emit(OpCodes.Stind_I8);
+ break;
+ case TypeCode.Single:
+ ilGenerator.Emit(OpCodes.Stind_R4);
+ break;
+ case TypeCode.Double:
+ ilGenerator.Emit(OpCodes.Stind_R8);
+ break;
+ default:
+ if (type.IsValueType)
+ {
+ ilGenerator.Emit(OpCodes.Stobj, type);
+ }
+ else
+ {
+ ilGenerator.Emit(OpCodes.Stind_Ref);
+ }
+ break;
}
}
diff --git a/tests/AspectCore.Extensions.Autofac.Test/AspectCore.Extensions.Autofac.Test.csproj b/tests/AspectCore.Extensions.Autofac.Test/AspectCore.Extensions.Autofac.Test.csproj
index 44e8eb14..9061bea9 100644
--- a/tests/AspectCore.Extensions.Autofac.Test/AspectCore.Extensions.Autofac.Test.csproj
+++ b/tests/AspectCore.Extensions.Autofac.Test/AspectCore.Extensions.Autofac.Test.csproj
@@ -27,8 +27,6 @@
-
-
diff --git a/tests/AspectCore.Extensions.Autofac.Test/Fakes/FakeServiceWithOut.cs b/tests/AspectCore.Extensions.Autofac.Test/Fakes/FakeServiceWithOut.cs
new file mode 100644
index 00000000..6e73beac
--- /dev/null
+++ b/tests/AspectCore.Extensions.Autofac.Test/Fakes/FakeServiceWithOut.cs
@@ -0,0 +1,37 @@
+using System.Globalization;
+using System.Threading.Tasks;
+using AspectCore.DynamicProxy;
+
+namespace AspectCore.Extensions.Test.Fakes
+{
+ public class FakeServiceWithOutInterceptor : AbstractInterceptorAttribute
+ {
+ public override async Task Invoke(AspectContext context, AspectDelegate next)
+ {
+ await next(context);
+ }
+ }
+
+ [FakeServiceWithOutInterceptor]
+ public interface IFakeServiceWithOut
+ {
+ bool OutDecimal(out decimal num);
+
+ bool OutInt(out int num);
+ }
+
+ public class FakeServiceWithOut : IFakeServiceWithOut
+ {
+ public bool OutDecimal(out decimal num)
+ {
+ num = 1.0M;
+ return true;
+ }
+
+ public bool OutInt(out int num)
+ {
+ num = 1;
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/AspectCore.Extensions.Autofac.Test/RegistrationExtensionsTests.cs b/tests/AspectCore.Extensions.Autofac.Test/RegistrationExtensionsTests.cs
index f93c4429..63ca8c50 100644
--- a/tests/AspectCore.Extensions.Autofac.Test/RegistrationExtensionsTests.cs
+++ b/tests/AspectCore.Extensions.Autofac.Test/RegistrationExtensionsTests.cs
@@ -1,5 +1,6 @@
using System.Reflection;
using AspectCore.Configuration;
+using AspectCore.DependencyInjection;
using AspectCore.DynamicProxy;
using AspectCore.Extensions.Autofac;
using AspectCore.Extensions.Test.Fakes;
@@ -67,5 +68,31 @@ public void AsProxyWithParamter_Test()
var proxyController = container.Resolve();
Assert.Equal(proxyService.Get(100), proxyController.Execute());
}
+
+ [Fact]
+ public void Intercept_OutWithDecimalParamter_Test()
+ {
+ var builder = CreateBuilder();
+ builder.RegisterType().As();
+ var container = builder.Build();
+
+ var proxyServiceWithOut = container.Resolve();
+ decimal num;
+ Assert.True(proxyServiceWithOut.OutDecimal(out num));
+ Assert.Equal(1.0M, num);
+ }
+
+ [Fact]
+ public void Intercept_OutWithIntParamter_Test()
+ {
+ var builder = CreateBuilder();
+ builder.RegisterType().As();
+ var container = builder.Build();
+
+ var proxyServiceWithOut = container.Resolve();
+ int num;
+ Assert.True(proxyServiceWithOut.OutInt(out num));
+ Assert.Equal(1, num);
+ }
}
}
diff --git a/tests/AspectCore.Tests/Classes.cs b/tests/AspectCore.Tests/Classes.cs
index 8bfdea8e..98764726 100644
--- a/tests/AspectCore.Tests/Classes.cs
+++ b/tests/AspectCore.Tests/Classes.cs
@@ -243,4 +243,35 @@ string IFakeExplicitImplementation.GetVal_NonAspect()
return "lemon";
}
}
+
+ public class FakeServiceWithOutInterceptor : AbstractInterceptorAttribute
+ {
+ public override async Task Invoke(AspectContext context, AspectDelegate next)
+ {
+ await next(context);
+ }
+ }
+
+ [FakeServiceWithOutInterceptor]
+ public interface IFakeServiceWithOut
+ {
+ bool OutDecimal(out decimal num);
+
+ bool OutInt(out int num);
+ }
+
+ public class FakeServiceWithOut : IFakeServiceWithOut
+ {
+ public bool OutDecimal(out decimal num)
+ {
+ num = 1.0M;
+ return true;
+ }
+
+ public bool OutInt(out int num)
+ {
+ num = 1;
+ return true;
+ }
+ }
}
\ No newline at end of file
diff --git a/tests/AspectCore.Tests/DynamicProxy/AsyncAspectTests.cs b/tests/AspectCore.Tests/DynamicProxy/AsyncAspectTests.cs
index 3ad6a8b6..85a2641a 100644
--- a/tests/AspectCore.Tests/DynamicProxy/AsyncAspectTests.cs
+++ b/tests/AspectCore.Tests/DynamicProxy/AsyncAspectTests.cs
@@ -4,6 +4,7 @@
using System.Text;
using Xunit;
using System.Threading.Tasks;
+using AspectCore.DependencyInjection;
namespace AspectCore.Tests.DynamicProxy
{
diff --git a/tests/AspectCore.Tests/Injector/GenericTest.cs b/tests/AspectCore.Tests/Injector/GenericTest.cs
index 7bb93cb5..b30cdd68 100644
--- a/tests/AspectCore.Tests/Injector/GenericTest.cs
+++ b/tests/AspectCore.Tests/Injector/GenericTest.cs
@@ -32,11 +32,30 @@ public void Resolve_InstanceSimpleGeneric()
Assert.IsType>(service);
}
+ [Fact]
+ public void Intercept_OutWithDecimalParamter_Test()
+ {
+ var service = ServiceResolver.Resolve();
+ decimal num;
+ Assert.True(service.OutDecimal(out num));
+ Assert.Equal(1.0M, num);
+ }
+
+ [Fact]
+ public void Intercept_OutWithIntParamter_Test()
+ {
+ var service = ServiceResolver.Resolve();
+ int num;
+ Assert.True(service.OutInt(out num));
+ Assert.Equal(1, num);
+ }
+
protected override void ConfigureService(IServiceContext services)
{
services.Transients.AddType(typeof(ISimpleGeneric<>), typeof(SimpleGeneric<>));
services.Transients.AddDelegate(typeof(IDelegateSimpleGeneric<>), r => new SimpleGeneric());
services.Singletons.AddInstance(typeof(IInstanceSimpleGeneric<>), new SimpleGeneric());
+ services.Transients.AddType();
}
}
}
\ No newline at end of file