How get Attribute Value in CodeAttribute
Asked Answered
A

1

5

I wrote a method to get Attribute Value By Property:

public string GetAttributeValueByNameAttributeAndProperty(CodeClass cc, string nameAttribute, string nameProperty)
{
    var value = "";
    foreach(CodeAttribute ca in cc.Attributes) 
            { 
                if(ca.Name.Contains(nameAttribute) && ca.Value.Contains(nameProperty))
                {
                    value = ca.Value.Remove(0,ca.Value.IndexOf(nameProperty));
                    value = value.Replace(" ","");
                    if(value.Contains(","))
                        value = value.Remove(ca.Value.IndexOf(","));
                }
            }

     return value;
}

For Example: I have Attribute [Map(Name = "MenuItem, Availability" )]

I call GetAttributeValueByNameAttributeAndProperty( codeclass, "Map" , "Name") After that method get CodeAttribute.Value and return string: Name = "MenuItem, Availability" After I remove "Name = " and extra characters and Split by ","

But my Senior Programmer told me that this method is inflexible and I need to find a more convenient way get inner data in CodeAttribute.Value.

Do you have any ideas / examples?

Arsonist answered 29/4, 2015 at 13:28 Comment(3)
I have edited your title. Please see, "Should questions include “tags” in their titles?", where the consensus is "no, they should not".Micmac
I was looking for a way to read attribute values using code model. Then I came to your question and since it didn't have an answer so I posted one. I know the question is rather old and probably you don't need the answer anymore, but future readers may find it useful :)Yuma
Thanks for the contribution :) Hope it will help anybody :) I eventually rewrote my t4 script into another script using Roslyn, since Roslyn provides a deep analyser of classes, attributes...Arsonist
Y
3

You can use CodeClass.Attributes property to get attributes of a class. Each attribute is of type of CodeAttribute and has a Name and a Children property which contains arguments of the attribute. Each argument is of type of CodeAttributeArgument which has Name and Value properties.

Example

Now you have all information which you need to get attribute value from CodeAttribute. Here is an example. I've decorated Program class with a [MySample(Property1 = "Something")] attribute

using System;
namespace ConsoleSample
{
    [MySample(Property1 = "Something")]
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
    public class MySampleAttribute : Attribute
    {
        public string Property1 { get; set; }
    }
}

And here is the sample T4 template:

<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".txt" #>
<#@ assembly Name="System.Core" #>
<#@ assembly name="EnvDte" #>
<#@ assembly name="EnvDte80" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections.Generic" #> 
<#@ import namespace="EnvDTE" #> 
<#@ import namespace="EnvDTE80" #> 
<#    
var env = (this.Host as IServiceProvider).GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
var project = env.Solution.FindProjectItem(this.Host.TemplateFile).ContainingProject
    as EnvDTE.Project;
var codeClass = project.ProjectItems.Item("Program.cs").FileCodeModel.CodeElements
                       .OfType<CodeNamespace>().ToList()[0]
                       .Members.OfType<CodeClass>().ToList()[0];
var attribute = codeClass.Attributes.Cast<CodeAttribute>()
                         .Where(a=>a.Name=="MySample").FirstOrDefault();
if(attribute!=null)
{
    var property = attribute.Children.OfType<CodeAttributeArgument>()
                            .Where(a=>a.Name=="Property1").FirstOrDefault();
    if(property!=null)
    {
        var value = property.Value;
        WriteLine(value);
    }
}
#>

If you run the template, you will receive "Something" in output.

Yuma answered 25/5, 2017 at 18:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.