我提出,建立在此基础上实现的接口接口的代理类发电机类。
看到我后上建立基于接口的代理类没有实现它 。
我熟悉CustomAttributeData.GetCustomAttributes(MemberInfo target)
,我用它当我读到接口的成员并成功将其导入到代理。
我想在注入运行时的附加属性生成的类。 我所要求的属性的实例将其注入到代理服务器。
例如:
开发人员可以通过这个作为一种价值: new ObsoleteAttribute("Demo", true)
,(它有一个空的构造,但属性是只读),我想将其转换为:
return new CustomAttributeBuilder(
attribute.GetType().GetConstructor(Type[] {typeof (string), typeof (bool)}),
new object[] {"Demo", true},
new FieldInfo[0],
new object[0]);
请记住,我不知道是什么给出。
这不是一般的解决方案,但如果你愿意来约束你那些参数构造函数和读/写属性和字段支持的属性将工作
CustomAttributeBuilder BuildCustomAttribute(System.Attribute attribute)
{
Type type = attribute.GetType();
var constructor = type.GetConstructor(Type.EmptyTypes);
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
var propertyValues = from p in properties
select p.GetValue(attribute, null);
var fieldValues = from f in fields
select f.GetValue(attribute);
return new CustomAttributeBuilder(constructor,
Type.EmptyTypes,
properties,
propertyValues.ToArray(),
fields,
fieldValues.ToArray());
}
做一个通用的解决方案,你可以使用表达式。 这是比较复杂的,但将允许语法,如:
BuildCustomAttribute(() => new ObsoleteAttribute("Demo", true));
解析表达式提取构造信息和参数将是复杂的一部分,但它可以做到的。
CustomAttributeBuilder BuildCustomAttribute(Expression<Action> exp)
{
//extract ConstructorInfo from exp
//extract ParameterValues from exp
//extract Attribute Type from exp
return new CustomAttributeBuilder(ConstructorInfo, ParameterValues);
}
谢谢乔,
我找到了Expression
的解决方案属性生成器 ,感谢您的输入。
我愿意工作有点困难,现在让其他开发者更容易使用我的代理服务器 。
我希望它可以更容易,如果我有属性的情况下,为什么我不能使用它的值并应用属性?
如果您有没有一个解决办法Expression
,我很想听到它。
这里是我的解决方案Expression
基于属性生成器 :
private CustomAttributeBuilder GetCustumeAttributeBuilder(Expression<Func<Attribute>> attributeExpression)
{
ConstructorInfo constructor = null;
List<object> constructorArgs = new List<object>();
List<PropertyInfo> namedProperties = new List<PropertyInfo>();
List<object> propertyValues = new List<object>();
List<FieldInfo> namedFields = new List<FieldInfo>();
List<object> fieldValues = new List<object>();
switch (attributeExpression.Body.NodeType)
{
case ExpressionType.New:
constructor = GetConstructor((NewExpression)attributeExpression.Body, constructorArgs);
break;
case ExpressionType.MemberInit:
MemberInitExpression initExpression = (MemberInitExpression)attributeExpression.Body;
constructor = GetConstructor(initExpression.NewExpression, constructorArgs);
IEnumerable<MemberAssignment> bindings = from b in initExpression.Bindings
where b.BindingType == MemberBindingType.Assignment
select b as MemberAssignment;
foreach (MemberAssignment assignment in bindings)
{
LambdaExpression lambda = Expression.Lambda(assignment.Expression);
object value = lambda.Compile().DynamicInvoke();
switch (assignment.Member.MemberType)
{
case MemberTypes.Field:
namedFields.Add((FieldInfo)assignment.Member);
fieldValues.Add(value);
break;
case MemberTypes.Property:
namedProperties.Add((PropertyInfo)assignment.Member);
propertyValues.Add(value);
break;
}
}
break;
default:
throw new ArgumentException("UnSupportedExpression", "attributeExpression");
}
return new CustomAttributeBuilder(
constructor,
constructorArgs.ToArray(),
namedProperties.ToArray(),
propertyValues.ToArray(),
namedFields.ToArray(),
fieldValues.ToArray());
}
private ConstructorInfo GetConstructor(NewExpression expression, List<object> constructorArgs)
{
foreach (Expression arg in expression.Arguments)
{
LambdaExpression lambda = Expression.Lambda(arg);
object value = lambda.Compile().DynamicInvoke();
constructorArgs.Add(value);
}
return expression.Constructor;
}
如果我理解正确的问题,这应在自定义属性添加到生成的类型
public class CustomAttribute: System.Attribute
{
public CustomAttribute()
{
}
}
TypeBuilder typeBuilder = module.DefineType(...)
....
typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(
typeof(CustomAttribute).GetConstructor(Type.EmptyTypes),
Type.EmptyTypes,
new FieldInfo[0],
new object[0]));
文章来源: Reflection Emit: how to Convert Attribute instance to CustomAttributeBuilder or CustomAttributeData