Reading the attributes of a type's attributes

Topics: Metadata Model, PE reader
Jun 16, 2009 at 4:07 PM


I'm trying to evaluate the attributes of a type via ITypeDefinition.Attributes, look at the attribute's type via ICustomAttribute.Type, and then via this ITypeReference inspect the attribute type's attributes via ITypeReference.Attributes.  In other words, I want to look at the attributes of the attributes of a type.  For example (this is not my exact scenario, but a similar pattern), if I wanted to look at the [AttributeUsage] of a type's attributes.

With the FxCop version of CCI, this seemed to just work as long as the assemblies that defined the attributes were in the same directory.  The problem that I had with this is that the assemblies were not always in the same directory.  I was hoping to get some control over the search logic by implementing IMetadataReaderHost in the new CodePlex version of CCI, but this didn't seem to help; in the scenario described above, when I try to access the attributes of the attribute, ITypeReference.Attributes is empty.

Any suggestions on how to do this?  Thanks.

Jun 16, 2009 at 4:24 PM

A reference to a type can have attributes that are distinct from the attributes of the type that is being referenced. In practise, no-one uses attributes on references (and there is no way to define such attributes using C#), but the metadata format allows for this.

At any rate, you need to resolve ICustomAttribute.Type. I.e. use ICustomAttribute.Type.ResolvedType. In the case where the custom attribute type is from another assembly, this will cause calls the the host object that will allow you control where to look for the other assembly.

Jun 16, 2009 at 10:02 PM

Thanks for the response. I didn't realize that it was possible for a type reference to have its own distinct attributes, that's very interesting. 

I tried using ResolvedType as you suggested, but I always get back an instance of DummyNamespaceTypeDefinition.  I have breakpoints set in every member that implements IMetadataHost and IMetadataReaderHost and as far as I can tell I'm not getting a call related to resolving the type reference's type or its assembly.  Which method on the host should be called when ICustomAttribute.Type.ResolvedType is called?  Is there anything else that I need to do to get the real resolved types instead of DummyNamespaceTypeDefinition?  Thanks.

Jun 17, 2009 at 5:33 AM

Resolving a type from another assembly that is not already loaded into the host should cause a call back to this method:

     /// <summary>
    /// This method is called when the assembly reference is being resolved and its not already loaded by the host.
    /// </summary>
    /// <param name="referringUnit">The unit that is referencing the assembly.</param>
    /// <param name="referencedAssembly">Assembly identifier for the assembly being referenced.</param>
    void ResolvingAssemblyReference(IUnit referringUnit, AssemblyIdentity referencedAssembly);