我正在尝试使用CCI-Metadata来创建代码生成器,迭代一组程序集,发现类型及其元数据,然后生成代码。我希望能够通过将自定义属性附加到原始类型的元数据来控制代码生成。
类似的东西:
[GenerateSpecialClass(true, "foo", IsReallySpecial=false)]
public class MyClass { ... }
我有一个INamedTypeDefinition并从Attributes属性中获取IEnumerable。从这里开始,我无法弄清楚如何获取自定义属性及其属性的值。
有人可以给我一个代码示例:给定一个ICustomAttribute,我如何从我的example属性中检索值。假设它的定义是:
public GenericSpecialClassAttribute : Attribute
{
public bool Prop1 { get; set; }
public string Prop2 {get; set; }
public bool IsReallySpecial {get; set; }
public GenericSpecialClassAttribute(bool prop1, string prop2)
{
Prop1 = prop1;
Prop2 = prop2;
}
}
非常感谢任何帮助。我假设我把它转换到其他界面并做了一些神奇的事情;但我找不到一个帮助它的帮助器,并且不完全理解实现/模型层次结构。
答案 0 :(得分:1)
尝试转换为Microsoft.Cci::IMetadataConstant
。以下是从Microsoft.Cci::ICustomAttribute
转储数据的示例代码。
public static void parseCustomAttribute(Cci::ICustomAttribute customAttribute)
{
foreach (Cci::IMetadataNamedArgument namedArg in customAttribute.NamedArguments)
{
parseNamedArgument(namedArg);
}
foreach (Cci::IMetadataExpression arg in customAttribute.Arguments)
{
parseFixedArgument(arg);
}
Console.WriteLine("Type Reference:\t\t"+ customAttribute.Type.ToString());
var constructor = customAttribute.Constructor as Cci::IMethodDefinition;
if (constructor != null)
{
//parseMethodDefinition(constructor);
}
else
{
//parseMethodReference(constructor);
}
}
private static void parseFixedArgument(Cci::IMetadataExpression fixedArgument)
{
Console.WriteLine("Type Reference:\t\t" + fixedArgument.Type.ToString());
var constValue = fixedArgument as Cci::IMetadataConstant;
if (constValue != null)
{
Console.WriteLine("Value :" + constValue.Value);
}
}
private static void parseNamedArgument(Cci::IMetadataNamedArgument namedArg)
{
Console.WriteLine("Name:" + "\t\t" + namedArg.ArgumentName.Value);
parseFixedArgument(namedArg.ArgumentValue);
}
IMetadataNamedArgument
是指元数据中Value
blob流中的名称/值对。它们用于指定字段和属性。对于您的课程,CCI将IsReallySpecial
作为IMetadataNamedArgument
IMetadataExpression
指的是构造函数的参数值。因此,args prop1
和prop2
在CCI对象模型中保留为MetadataExpression
。答案 1 :(得分:0)
查看Jason Bock的Injectors。我认为他在他的InjectorContext.Find()方法中做了你正在寻找的东西,然后在NotNullInjector.OnInject()方法中查找不同的属性/参数。
启动并运行他的代码,然后您将更好地了解如何执行您要执行的操作。