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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With