1

I'm attempting to use CCI-Metadata for creating a code generator, by iterating over a set of assemblies, discovering the types and their metadata and then generating the code. I would like to be able to control the code generation by attaching custom attributes to the metadata of the original types.

Something like:

[GenerateSpecialClass(true, "foo", IsReallySpecial=false)]
public class MyClass { ... }

I have a INamedTypeDefinition and get an IEnumerable from the Attributes property. From here, I can't figure out what to do to get the value of custom attribute and it's properties.

Could someone give me a code sample: given an ICustomAttribute, how I can retrieve the values from my example attribute. Assume it's definition is:

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;
    } 
}

Any help would be very much appreciated. I assume I cast this to some other interface and do something magical on it; but I couldn't find a helper that did anything with it and don't fully understand the implementation/model hierarchy.

4

2 回答 2

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);
}
  • IMetadataNamedArgumentValue元数据中 blob 流中的名称/值对。它们用于指定字段和属性。对于您的班级,CCIIsReallySpecial可作为IMetadataNamedArgument
  • IMetadataExpression指的是构造函数的参数值。所以 argsprop1prop2保存MetadataExpression在 CCI 对象模型中。
于 2012-12-15T10:10:23.717 回答
0

查看 Jason Bock 的注射器。我认为他在他的 InjectorContext.Find() 方法中做了您正在寻找的事情,然后在 NotNullInjector.OnInject() 方法中查找不同的属性/参数。

启动并运行他的代码,然后您将更好地了解如何做您想做的事情。

于 2010-01-31T13:42:53.017 回答