Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Add-ins for Generating Properties from Class Variables in Visual Studio .NET

2.89/5 (9 votes)
5 Aug 2010CPOL2 min read 40.4K   706  
Add-in Visual Studio 2008 for automatically generating properties (Getter and Setter)
Before

Before

After

After

Introduction

In Visual Studio (VS), you must type property or generate it one by one. It's tedious if you have a lot of variables. This properties generator manages the properties creation and modification. So if you have ten variables with a snippet, you must call it ten times. With the properties generator, in one time, all variables of your choice are generated.

Background

In this article, I suppose than you know the base for developing add-ins. You can read this article if you do not know this base.

Using the Code

For using, the *.AddIn and the *.dll must be present in My Documents\Visual Studio 2008\Addins:

  • ClassField.cs is a little class created for content information on variable and property of this variable.
  • ClassManager.cs used for retrieve class, variable and write property.
  • ClassStruct contains the interface Istruct, this interface encapsulates CodeClass and CodeStruct. CodeClass is a VS object which contains information on Class and CodeStruct information on Struct.

ClassManager

The constructor of this class takes a DTE2, it is an object of Visual Studio. With this object, we can retrieve in the active document all code elements (Namespace, Class, ...). For this, we use two methods, ProcessElement and LoadClass.

ProcessElement(CodeElement elem) is a recursive method used for finding Class or Struct present in the active document. We can know the type of the element with this property kind. Class or Struct found are stocked in m_Classes. It is used for binding the combobox with all class names. When the combobox is changed, we call the method LoadClass(IStruct mclass).

LoadClass(Istruct mclass) retrieves variable and properties present in mclass and this bases. This method returns a list of ClassField used for creating the treeview.

C#
private bool LoadClasses()
{
    m_Classes = new List<IStruct>();
    if (((this.m_applicationObject.ActiveDocument == null) || 
	(this.m_applicationObject.ActiveDocument.ProjectItem == null)) || 
	((this.m_applicationObject.ActiveDocument.ProjectItem.FileCodeModel == null) || 
	(this.m_applicationObject.ActiveDocument.ProjectItem.FileCodeModel.CodeElements 
								== null)))
    {
        return false;
    }
    else
    {
        foreach (CodeElement element in 
	this.m_applicationObject.ActiveDocument.ProjectItem.FileCodeModel.CodeElements)
        {
            this.ProcessElement(element);
        }
    }
    return true;
}

/// <summary>
/// Retrieve all 'class' and 'struct' in the active document
/// </summary>
/// <param name="elem"></param>
/// <param name="rootName"></param>
private void ProcessElement(CodeElement elem)
{
    if (elem.Kind == vsCMElement.vsCMElementNamespace)
    {
        CodeNamespace namespac = elem as CodeNamespace;
        foreach (CodeElement element in namespac.Members)
        {
            this.ProcessElement(element);
        }
    }
    else if (elem.Kind == vsCMElement.vsCMElementClass)
    {
        ClassStructure item = new ClassStructure(elem as CodeClass);
        this.m_Classes.Add(item);
        foreach (CodeElement element2 in item.Members)
        {
            this.ProcessElement(element2);
        }
    }
    else if (elem.Kind == vsCMElement.vsCMElementStruct)
    {
        StructStructure struct3 = new StructStructure(elem as CodeStruct);
        this.m_Classes.Add(struct3);
    }
}  

For writing or remove a property, we use EditPoint which is a VS object for manipulating the text. But before if the property does not exist, we create it with a call to m_currentStructure.AddProperty. m_currentStructure is the current Istruct. AddProperty method creates a new property code construct and inserts the code in the correct location. For the location, if it is a CodeElement the property is created after it, 0 creates the new element at the beginning and -1 at the end. But this property is empty, we retrieve the start point of the property (get or set) and the end and deleted this selection point.Delete(point2); after the delete of the empty property, we write our property point.Insert(field.GetMethod). If a property already exists, we insert a new line and write the property (get or set) we want.

For deleting a property, we select the start point and the end of the property, after we delete the selection:

C#
public void WriteProperty(ClassField field, bool createGet, 
	bool createSet,bool setIsInternal, object position)
{
    CodeProperty property;
    //if null, create a new property else modify
    if (field.Property == null)
    {
        property = this.m_currentStructure.AddProperty
		(field, createGet, createSet, position);
        //Create summary
        EditPoint pt = property.StartPoint.CreateEditPoint();
        pt.LineUp(1);
        pt.Insert(string.Format(@"
/// <summary>
/// {0}{1}{2}
/// </summary>",
           createGet ? "Gets" : string.Empty,
           createSet && createGet ? "/" : string.Empty,
           createSet ? "Sets" : string.Empty));
           
        if (createGet)
        {
            property.Getter.IsShared = field.Field.IsShared;
            EditPoint point = property.Getter.StartPoint.CreateEditPoint();
            EditPoint point2 = property.Getter.EndPoint.CreateEditPoint();
            point.Delete(point2);
            point.Insert(field.GetMethod);
        }
        if (createSet)
        {
            property.Setter.IsShared = field.Field.IsShared;
            EditPoint point = property.Setter.StartPoint.CreateEditPoint();
            EditPoint point2 = property.Setter.EndPoint.CreateEditPoint();
            point.Delete(point2);
            point.Insert(field.SetMethod(setIsInternal));
        }
    }
    else
    {
        property = field.Property;
        if (createGet)
        {
            EditPoint point = property.Getter.EndPoint.CreateEditPoint();
            point.Insert(Environment.NewLine);
            point.Insert(field.GetMethod);
            EditPoint point2 = property.StartPoint.CreateEditPoint();
            EditPoint point3 = property.EndPoint.CreateEditPoint();
            point2.SmartFormat(point3);                
        }
        if (createSet)
        {
            EditPoint point = property.Getter.EndPoint.CreateEditPoint();
            point.Insert(Environment.NewLine);
            point.Insert(field.SetMethod(setIsInternal) );
            EditPoint point2 = property.StartPoint.CreateEditPoint();
            EditPoint point3 = property.EndPoint.CreateEditPoint();
            point2.SmartFormat(point3);               
        }
    }
}
C#
class ClassField
{
     	public string GetMethod
         {
            get
            {
                return string.Format("get {{ return {0}{1}; }}",
		this.m_Field.IsShared ? "" : "this.", this.m_Field.Name);
            }
         }

	public string SetMethod(bool isInternal)
         {
                return string.Format("{2}  set {{ {0}{1} = value; }}", 
		this.m_Field.IsShared ? "" : "this.", this.m_Field.Name, isInternal ? 
		"internal" : string.Empty );
         }
}

History

  • 22/12/2009 - Version 1.0

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)