Monday, October 25, 2010

NDepend

Recently I was presented with an opportunity and the pro licence by Patrick Smacchia lead developer NDepend tool , to test run the NDepend 3.2.0.5097 and list its unique and amazing features.


NDepend is the great tool for analysing the .Net code base and measuring the quality of code via various code metrics presented by the NDepend analysis. Analysis of the code is presented in nice visual layout , so it is easy to get a quick summary of all the related information. Its makes the job very easy while you are trying to understand the code workflow designed by others .


I am currently in process of exploring the NDepend tool and running it against various small and large code bases to effectively check out and understand the analysis presented by NDepend.


I will be soon writing some detailed benifits of NDepend and its impact on overall software quality. Until then I will like my readers to check out the amazing features of NDepend at


http://www.ndepend.com/# .


If you find it interesting enough then you can download the trial version of NDepend from :-


http://www.ndepend.com/NDependDownload.aspx


and check out yourself for the
effectivness.

SharpDevelop:- ProjectItems

This blog entry will be all about adding the projectitem to the SharpDevelop project. In SharpDevelop we get project service from the class "ProjectService" that lets us to add various type of project item to the SharpDevelop project and bind to the the different project related events. ProjectService class can be found in main base addin ("\Project\Src\Services\ProjectService\ProjectService.cs"). SharpDevelop project item can be of different types like cs/vb files , project references , webreferences etc. Main base class for all the project items in SharpDevelop is "ProjectItem" Class from which all the derived project item classes evolve like FileProjectItem, ReferenceProjectItem, WebReferenceProjectItem etc.
In this blog we will see the addition of assembly references and the addition of cs/vb class files to the SharpDevelop Project at runtime.

Once the project is opened in the SharpDevelop we can access the current project via ProjectService class ( "ProjectService.CurrentProject" property ).

To add the assembly reference at runtime we have to create the instance of ReferenceProjectItem and provide the current project instance and the assembly name in the constructor.

ReferenceProjectItem item = new ReferenceProjectItem(ProjectService.CurrentProject, Path.GetFileNameWithoutExtension(my_exsistingCSFilePath));

Prior to adding the assembly reference to the Project , we can check if assembly reference is already added to the Project. We can check that by checking all the current project items .

IProject project = ProjectService.CurrentProject;


ProjectItem proitem = (from proI in project.Items.AsEnumerable() where Path.GetFileNameWithoutExtension(proI.FileName) == Path.GetFileNameWithoutExtension (my_exsistingCSFilePath) select proI).SingleOrDefault();


if (proitem != null){ ProjectService.RemoveProjectItem(project, proitem);
}


After checking for the exsistence of the assembly reference we can add the assembly reference to the Project at runtime by:-


ProjectService.AddProjectItem(project, item);


project.Save();


ProjectBrowserPad.RefreshViewAsync();


To add the cs/vb project item to Project at runtime , we have to create the instance of "FileProjectItem" and provide appropriate parameters to the constructor.

IProject project = ProjectService.CurrentProject;


string relFileName = FileUtility.GetRelativePath(project.Directory, filePath);


FileProjectItem fileProjectItem = new FileProjectItem(project, project.GetDefaultItemType(filePath), relFileName);


Then we can add the file to the current project , following the same procedure as we did in addition of assembly reference.

ProjectItem item = (from proI in project.Items.AsEnumerable() where Path.GetFileName(proI.FileName) == Path.GetFileName(filePath) select proI).SingleOrDefault();


if(item != null) {ProjectService.RemoveProjectItem(project, item); }


FileNode fileNode = new FileNode(filePath, FileNodeStatus.InProject);

fileNode.ProjectItem = fileProjectItem; ProjectService.AddProjectItem(project, fileProjectItem);

project.Save();

ProjectBrowserPad.RefreshViewAsync();


In this same way we can add WebReferences and all other project items to the SharpDevelop Project.

Friday, October 22, 2010

SharpDevelop :- ReferencePath

Adding Referencepath property to the SharpDevelop project property page programmatically. This is the topic of this blog. I wanted to add runtime generated reference path to the project property page. SharpDevelop provide Project service for managing the project related funtionality. ProjectService class contains many static method and events that can be used to load the new project to the solution or add exsisting project to the solution. ProjectService also exposes many events that are raised when project is added.removed or projectitem are added or removed.

I decided to add the dynamically generated reference path to the project after the project is loaded inside the SharpDevelop. For this I subscribed to the ProjectCreated event of ProjectService class .

ProjectService.ProjectCreated -= new ProjectEventHandler(ProjectService_ProjectCreated);

So whenever a new project is added to the solution , i can get the event and add my reference path to the project property. When we get the ProjectCreated event we get the ProjectEventArgs as the parameter. ProjectEventArgs contains the property Project which is of type IProject . We have to cast the Project property to MSBuildBasedProject .

MSBuildBasedProject is class that is responsible for the generating and setting the MSBuild items and properties from the in memory representation of project and project items.

Now we have to call the SetProperty method of MSBuildBasedProject with proper property /value and call the Save method on the MSBuildBasedProject.

void ProjectService_ProjectCreated(object sender, ProjectEventArgs e){
MSBuildBasedProject msProject = e.Project as MSBuildBasedProject;
msProject.SetProperty("ReferencePath", myRefPath);
msProject.Save();
}

Thursday, October 21, 2010

SharpDevelop :-- Project Template

This blog is about creating custom project template and integrating it with the SharpDevelop Studio. Whenever we wanted to create a new project whether it is winform project , class library ,usercontrol etc ,we are presented with predefined project template in New Project Dialog Box. In Visual studio or VSTA the project templates are the msbuild project templates and are installed with the IDE . ShareDevelop project templates are the custom project template files similar to the VS templates with xml format. PropertyService of SharpDevelop contains all the info about the configurable and global properties. To get the path of the SharpDevelop project templates we can use PropertyService to find the path. PropertyService member DataDirectory gives us the location where project and file templates are stored .

So SharpDevelop project templates are stored at location :--

Path.Combine(PropertyService.DataDirectory, "templates", "project");

Under this path there are folders named "CSharp" and "VBNet" .These folder contains the respective project template for these languages. SharpDevelop project templates are xml file with extension ".xpt".

Lets examine the project template for example "FormsProject.xpt" .



<Template created="06/10/2001" templateType="MyTemplateCS">
<TemplateConfiguration>
<Name>MyTemplate</Name>
<Category>C#</Category>
<Subcategory>MyCatagory</Subcategory>
<Icon>C#.Project.Library</Icon>
<Description>Template for Workflow.</Description>
<SupportedTargetFrameworks>v2.0;v3.5Client</SupportedTargetFrameworks>
</TemplateConfiguration>
<Actions>
<Open filename="Main.cs" />
</Actions>
<Project language="C#">
<ProjectItems>
<Reference Include="System" />
<Reference Include="System.Data" />
</PROJECTITEMS/> language=C# name="Data_Buzz.cs" Library<> <> >
<![CDATA[
/* Our code goes here */
]]>
<</File>
</Files>
</Project>
</Template>



We can see that SharpDevelop Project Template is similar to the msbuild project template. There is opening node "Template" that has some attribute defining the general info about the template. Then comes the "TemplateConfiguration" that tells the template configuration :-

Name :- name of the template

Category :- the main folder under which to show this template in New Project Dialogbox.

SubCategory :- the folder under main folder under which to show this project template in New Project Dialog box.

Icon :- icon to show on the project template shown in New Project Dialogbox.
Supported target framework :- the .net target framework.

"Actions" node tells us which file to open up in ShareDevelop IDE when the project template is loaded. It defines the child node "Open" with attribute "filename" that defines the file to open in SharpDevelop workspace after the project is loaded. Then comes the node "Project" defining the attribute "language" .

Under Project node comes "ProjectItems" which contains the child nodes of type "reference". These nodes of type "reference" tells us what assemblies to add up as references to the project when it is loaded up in SharpDevelop IDE.

Project node also contain the child node "PropertyGroup" which contains the node about the information of the project type (exe or library) under node "OutputType".
In case of msbuild project templates we have code file (.cs or .vb) in separate files and info of these file are stored in project templates. But in SharpDevelop the code files to generate along with the project are defined inside the project template. "Project" node in project template defines the node "Files" which in turn contains the child nodes "File". "File" node contains the attributes name and language defiining the name and language of .cs or .vb file . Under "File" node there is CDATA section which contains all the code for file .

Now lets see how these templates are loaded in SharpDevelop. We can locate the New Project DialogBox under the base addin code (ICSharpCode.SharpDevelop.Project.Dialogs) . Base addin is the project (ICSharpCode.SharpDevelop.csproj) and New Project DialogBox is located at "\src\gui\dialogs". The constructor of New Project DialogBox contains the method "InitializeTemplates()" . In this method project templates are iterated and filled up in the listview of the NewProject DialogBox. The collection of project templates are fetched from the ProjectTemplate class's public property "ProjectTemplates". If we go inside the ProjectTemplate class and look at ProjectTemplates property we can see the get part of property returns ProjectTemplate Collection after calling the "UpdateTemplate()" method.

"UpdateTemplate()" method is responsible for creating the project template collection.It contains the code to load all the project templates from the DataDirectory and create in memory representation of project template xml files. So the instance of class ProjectTemplate is the runtime representation of the project template files residing in the DataDirectory.

ProjectTemplate class also contains the public property ProjectDescriptor , this property is of type "ProjectDiscriptor". Instance of ProjectDiscriptor class is also created by the Project template class and it contains the information about the files of the Project . ProjectDiscriptor class holds the in memory representation of the file node in the ProjectTemplate xml file.

So to create our own project template we have to create the ".xpt" xml project template file and place it in the DataDirectory under relative language folder (CSharp or VBNet). SharpDevelop will automatically load the project when the New Project DialogBox is opend.

If your project files are generated at runtime from other system and you have to create new project template based on them , then you have to create the project template at runtime and save it to the DataDirectory. Then you have to call the static method UpdateTemplate() of ProjectTemplate class to reload the Project template .

Tuesday, October 19, 2010

SharpDevelop

Recently , I started working with the SharpDevelop , open source IDE for the .Net platform . It is same as NetBeans and Visual Studio IDE and provides almost same features . Previously I have worked on VSTA as tool for developing addin's for a application. VSTA is the subset of Visual studio and provided many ways to extend the IDE . I have done many customization in the IDE with VSTA programming interface. In VSTA using ENVDTE namespace we get hold of the extensibility framework for IDE and its funtionalities. We can provide our own custom menu, menuitems, toolbar,toolbar items , we can extend the contextmenus of IDE , get hold of many IDE command like build ,rebuild, edit many properties of the IDE like platform target, reference path, active configuration etc. Apart form all these we can define our own project templates, wizards (IDEWizards) etc and can add projects and project items at runtime. We can use CodeDom to generate code , create assemblies and build them.

Can I achieve same thing using ShareDevelop ? To find out that, I got source code of ShareDevelop and started digging it. Sharpdevelop is based on addin model . It consist of a small core and all its functionalities are held by addins . Core contains the code to extend the SharpDevelop via all the other addin's. SharpDevelop Addin's are simple xml files and the binaries associated with them (.dll etc). For example Addin name myaddin will have a single xml file with extension .addin :- myaddin.addin and one or more binaries having the implementation of addin (myaddin.dll ). Xml file contain some nodes specific to the addin general information .Main thing to notice in addin xml are the extension nodes .Extension nodes starts with the name path which has the attribute named "name" that defines the path where this extension will be added up on the SharpDevelop core.

<path name="/SharpDevelop/Workspace/MainMenu">;

SharpDevelop contains this concept of paths . SharDevelop core and the addin responsible for the base functionality of the SharpDelvelop (ICSharpCode.SharpDevelop.addin) defines some paths upon which the functionalities can be extended. Paths represent the way via which we can find a node in a tree where "/" defines the root node. In fact the SharpDevelop maintains the tree structure for all the addin's that extend it . So we can extend the base with a addin and that addin will become the tree node for addin tree.If that addin defines a extension point then further a next addin can extend this addin. This features of extending a existing addin is not there in VSTA framework. SharpDevelop core contains many services for basic functionalities like property, resource, gui etc handling. Another concept other than paths are codons. In addin xml file we can find the codons as :--


<Path name = "/SharpDevelop/Workspace/MainMenu">
<MenuItem id = "File" label = "&File">
<MenuItem id = "Separator1" label = "-"/>
<MenuItem id = "Exit"
label = "E&xit"
class = "NCvs.Gui.Commands.ExitCommand"/>
</MenuItem>
</Path>



-

We can see all the elements inside the path node . As i have said, path node defines the extension point in SharpDevelop and it also defines the node that will be added to MainMenu of SharpDevelop . What about the elements inside path node, they all are codons. Codons are the element that specify the behaviour of the elements inside the program. So path tells us the extension point and the menuitem "File" is added under this path node. Menuitem "File" also contains the element Menuitem "Seperator1 " and "Exit". These codons will arranged under the "File" codon which is under the MainMenu path. No we have a treenode under the path Mainmenu. What we get from example is that SharDevelop contains a AddIn Tree that contains the AddIn Tree Nodes , AddIn tree nodes conatin the AddIns and in turn Addins contain the Codons. Addin Tree contains various service to load the addins and build the tree. AddinTreeNode conatins the method BuildChildItems that returns the list of all the built codons from a addin. Addin class contains all the information about the codons inside it and all the info of assemblies needed to create the runtime object of the codon. It gets all this info from the xml file . Codon class contains a methos Buiditem that creates the runtime instance of the codon. So the built codon is the in memory representation of the codon item in addin xml file. Shardevelop core contains many builder and factory classes to load the assemblies containg the codon definitions and build the in memory tree for the Addin from addin xml file and entire AddIn tree.

But can I do all the stuff that I did with VSTA , described above at starting ? I think with the help of Base Addin i can start experimenting . In next post I will start with creating our own project template in SharpDevelop. Hope ,somebody will find it useful.

http://www.codeproject.com/KB/cs/ICSharpCodeCore.aspx
http://www.icsharpcode.net/opensource/sd/
http://sharpdevelop.codeplex.com/