Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/missing attributes for dynamic proxy #269

Merged
merged 3 commits into from
Aug 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 30 additions & 19 deletions src/AspectCore.Core/Utils/ProxyGeneratorUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private Type CreateInterfaceImplInternal(string name, Type interfaceType, Type[]
var typeDesc = TypeBuilderUtils.DefineType(_moduleBuilder, _proxyNameUtils.GetProxyTypeName(_proxyNameUtils.GetInterfaceImplTypeName(interfaceType), interfaceType, implType),
interfaceType, typeof(object), interfaceTypes);

typeDesc.Properties[typeof(IAspectValidator).Name] = aspectValidator;
typeDesc.Properties[nameof(IAspectValidator)] = aspectValidator;

//define constructor
ConstructorBuilderUtils.DefineInterfaceProxyConstructor(interfaceType, implType, typeDesc);
Expand All @@ -128,7 +128,7 @@ private Type CreateInterfaceProxyInternal(string name, Type interfaceType, Type

var typeDesc = TypeBuilderUtils.DefineType(_moduleBuilder, name, interfaceType, typeof(object), interfaces);

typeDesc.Properties[typeof(IAspectValidator).Name] = aspectValidator;
typeDesc.Properties[nameof(IAspectValidator)] = aspectValidator;

//define constructor
ConstructorBuilderUtils.DefineInterfaceProxyConstructor(interfaceType, typeDesc);
Expand All @@ -147,7 +147,9 @@ private Type CreateClassProxyInternal(string name, Type serviceType, Type implTy

var typeDesc = TypeBuilderUtils.DefineType(_moduleBuilder, name, serviceType, implType, interfaces);

typeDesc.Properties[typeof(IAspectValidator).Name] = aspectValidator;
TypeBuilderUtils.DefineTypeAttributes(implType, typeDesc);

typeDesc.Properties[nameof(IAspectValidator)] = aspectValidator;

//define constructor
ConstructorBuilderUtils.DefineClassProxyConstructors(serviceType, implType, typeDesc);
Expand Down Expand Up @@ -233,14 +235,23 @@ public static TypeDesc DefineType(ModuleBuilder moduleBuilder, string name, Type
GenericParameterUtils.DefineGenericParameter(serviceType, typeBuilder);

//define default attribute
typeBuilder.SetCustomAttribute(CustomAttributeBuildeUtils.DefineCustomAttribute(typeof(NonAspectAttribute)));
typeBuilder.SetCustomAttribute(CustomAttributeBuildeUtils.DefineCustomAttribute(typeof(DynamicallyAttribute)));
typeBuilder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(typeof(NonAspectAttribute)));
typeBuilder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(typeof(DynamicallyAttribute)));

//define private field
var fieldTable = FieldBuilderUtils.DefineFields(serviceType, typeBuilder);

return new TypeDesc(serviceType, typeBuilder, fieldTable, new MethodConstantTable(typeBuilder));
}

public static void DefineTypeAttributes(Type implType, TypeDesc typeDesc)
{
//inherit implement type's attributes
foreach (var customAttributeData in implType.CustomAttributes)
{
typeDesc.Builder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(customAttributeData));
}
}
}

private class ConstructorBuilderUtils
Expand Down Expand Up @@ -312,12 +323,12 @@ internal static void DefineClassProxyConstructors(Type serviceType, Type implTyp
var parameters = new Type[] { typeof(IAspectActivatorFactory) }.Concat(parameterTypes).ToArray();
var constructorBuilder = typeDesc.Builder.DefineConstructor(constructor.Attributes, constructor.CallingConvention, parameters);

constructorBuilder.SetCustomAttribute(CustomAttributeBuildeUtils.DefineCustomAttribute(typeof(DynamicallyAttribute)));
constructorBuilder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(typeof(DynamicallyAttribute)));

//inherit constructor's attribute
foreach (var customAttributeData in constructor.CustomAttributes)
{
constructorBuilder.SetCustomAttribute(CustomAttributeBuildeUtils.DefineCustomAttribute(customAttributeData));
constructorBuilder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(customAttributeData));
}

ParameterBuilderUtils.DefineParameters(constructor, constructorBuilder);
Expand Down Expand Up @@ -450,12 +461,12 @@ private static MethodBuilder DefineMethod(MethodInfo method, string name, Method
GenericParameterUtils.DefineGenericParameter(method, methodBuilder);

//define method attributes
methodBuilder.SetCustomAttribute(CustomAttributeBuildeUtils.DefineCustomAttribute(typeof(DynamicallyAttribute)));
methodBuilder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(typeof(DynamicallyAttribute)));

//inherit targetMethod's attribute
foreach (var customAttributeData in method.CustomAttributes)
{
methodBuilder.SetCustomAttribute(CustomAttributeBuildeUtils.DefineCustomAttribute(customAttributeData));
methodBuilder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(customAttributeData));
}

//define paramters
Expand Down Expand Up @@ -798,12 +809,12 @@ private static PropertyBuilder DefineInterfaceProxyProperty(PropertyInfo propert
{
var propertyBuilder = typeDesc.Builder.DefineProperty(name, property.Attributes, property.PropertyType, Type.EmptyTypes);

propertyBuilder.SetCustomAttribute(CustomAttributeBuildeUtils.DefineCustomAttribute(typeof(DynamicallyAttribute)));
propertyBuilder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(typeof(DynamicallyAttribute)));

//inherit targetMethod's attribute
foreach (var customAttributeData in property.CustomAttributes)
{
propertyBuilder.SetCustomAttribute(CustomAttributeBuildeUtils.DefineCustomAttribute(customAttributeData));
propertyBuilder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(customAttributeData));
}

return propertyBuilder;
Expand Down Expand Up @@ -848,7 +859,7 @@ private static void DefineInterfaceImplProperty(PropertyInfo property, TypeBuild

foreach (var customAttributeData in property.CustomAttributes)
{
propertyBuilder.SetCustomAttribute(CustomAttributeBuildeUtils.DefineCustomAttribute(customAttributeData));
propertyBuilder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(customAttributeData));
}
}
}
Expand Down Expand Up @@ -883,20 +894,20 @@ public static void DefineParameters(MethodInfo targetMethod, MethodBuilder metho
}
}
}
parameterBuilder.SetCustomAttribute(CustomAttributeBuildeUtils.DefineCustomAttribute(typeof(DynamicallyAttribute)));
parameterBuilder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(typeof(DynamicallyAttribute)));
foreach (var attribute in parameter.CustomAttributes)
{
parameterBuilder.SetCustomAttribute(CustomAttributeBuildeUtils.DefineCustomAttribute(attribute));
parameterBuilder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(attribute));
}
}
}

var returnParamter = targetMethod.ReturnParameter;
var returnParameterBuilder = methodBuilder.DefineParameter(0, returnParamter.Attributes, returnParamter.Name);
returnParameterBuilder.SetCustomAttribute(CustomAttributeBuildeUtils.DefineCustomAttribute(typeof(DynamicallyAttribute)));
returnParameterBuilder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(typeof(DynamicallyAttribute)));
foreach (var attribute in returnParamter.CustomAttributes)
{
returnParameterBuilder.SetCustomAttribute(CustomAttributeBuildeUtils.DefineCustomAttribute(attribute));
returnParameterBuilder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(attribute));
}
}

Expand Down Expand Up @@ -1034,10 +1045,10 @@ internal static void DefineParameters(ConstructorInfo constructor, ConstructorBu
{
parameterBuilder.SetConstant(parameter.DefaultValue);
}
parameterBuilder.SetCustomAttribute(CustomAttributeBuildeUtils.DefineCustomAttribute(typeof(DynamicallyAttribute)));
parameterBuilder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(typeof(DynamicallyAttribute)));
foreach (var attribute in parameter.CustomAttributes)
{
parameterBuilder.SetCustomAttribute(CustomAttributeBuildeUtils.DefineCustomAttribute(attribute));
parameterBuilder.SetCustomAttribute(CustomAttributeBuilderUtils.DefineCustomAttribute(attribute));
}
}
}
Expand Down Expand Up @@ -1114,7 +1125,7 @@ private static GenericParameterAttributes ToClassGenericParameterAttributes(Gene
}
}

private class CustomAttributeBuildeUtils
private class CustomAttributeBuilderUtils
{
public static CustomAttributeBuilder DefineCustomAttribute(Type attributeType)
{
Expand Down
90 changes: 90 additions & 0 deletions tests/AspectCore.Tests/DynamicProxy/DefineAttributesTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Xunit;
using AspectCore.DynamicProxy;

namespace AspectCore.Tests.DynamicProxy
{
public class DefineAttributesTests : DynamicProxyTestBase
{
[Description(nameof(Service)), DefaultValue(nameof(Service))]
public class Service
{
[Description(nameof(OnMethod)), DefaultValue(nameof(OnMethod))]
public void OnMethod() { }

[Description(nameof(OnProperty)), DefaultValue(nameof(OnProperty))]
public virtual string OnProperty { get; set; }

[return: Description(nameof(OnReturn)), DefaultValue(nameof(OnReturn))]
public int OnReturn() => 1;

public void OnParameter([Description(nameof(OnParameter)), DefaultValue(nameof(OnParameter))] int arg) { }

public void OnGenericArgument<[Description(nameof(OnGenericArgument)), DefaultValue(nameof(OnGenericArgument))] T>() { }
}

private static void CheckAttribute<T>(IEnumerable<object> attributes, Action<T> check) where T : Attribute
{
var attribute = (T)attributes.FirstOrDefault(m => m.GetType() == typeof(T));
Assert.NotNull(attribute);
check(attribute);
}

private static void CheckAttributes(IEnumerable<object> attributes, string value)
{
CheckAttribute<DescriptionAttribute>(attributes, m => Assert.Equal(value, m.Description));
CheckAttribute<DefaultValueAttribute>(attributes, m => Assert.Equal(value, m.Value));
}

[Fact]
public void Attributes_OnClass_Test()
{
var service = ProxyGenerator.CreateClassProxy<Service>();
var attributes = service.GetType().GetCustomAttributes(true);
CheckAttributes(attributes, nameof(Service));
}

[Fact]
public void Attributes_OnMethod_Test()
{
var service = ProxyGenerator.CreateClassProxy<Service>();
var attributes = service.GetType().GetMethod(nameof(Service.OnMethod)).GetCustomAttributes(true);
CheckAttributes(attributes, nameof(Service.OnMethod));
}

[Fact]
public void Attributes_OnProperty_Test()
{
var service = ProxyGenerator.CreateClassProxy<Service>();
var attributes = service.GetType().GetProperty(nameof(Service.OnProperty)).GetCustomAttributes(true);
CheckAttributes(attributes, nameof(Service.OnProperty));
}

[Fact]
public void Attributes_OnReturn_Test()
{
var service = ProxyGenerator.CreateClassProxy<Service>();
var attributes = service.GetType().GetMethod(nameof(Service.OnReturn)).ReturnParameter.GetCustomAttributes(true);
CheckAttributes(attributes, nameof(Service.OnReturn));
}

[Fact]
public void Attributes_OnParameter_Test()
{
var service = ProxyGenerator.CreateClassProxy<Service>();
var attributes = service.GetType().GetMethod(nameof(Service.OnParameter)).GetParameters().Single().GetCustomAttributes(true);
CheckAttributes(attributes, nameof(Service.OnParameter));
}

[Fact]
public void Attributes_OnGenericArgument_Test()
{
var service = ProxyGenerator.CreateClassProxy<Service>();
var attributes = service.GetType().GetMethod(nameof(Service.OnGenericArgument)).GetGenericArguments().Single().GetCustomAttributes(true);
CheckAttributes(attributes, nameof(Service.OnGenericArgument));
}
}
}