5.5 SharpDevelop

SharpDevelop8 (#develop) is an open-source IDE for C#, VB.NET and Boo projects. It is a well known alternative to Microsoft Visual Studio for developing .NET applications. SharpDevelop is completely written in C#. The current released version 2.1 requires the Microsoft .NET Framework 2.0 to run. This IDE is chosen for the evaluation within this diploma thesis because of its architecture. The application consists of a small core which includes an add-in system. Everything outside the core is implemented as add-ins. This architecture supports the idea behind SharpDevelop that it should be an open IDE for various programming languages. Extending SharpDevelop with a new programming language can be done by writing a new add-in [HKS03, p. 8]. The important point is that SharpDevelop can be extended without the need of modifying existing code.

Add-In System

An add-in consists of an XML configuration file with the extension .addin and one or more assembly files. The configuration file contains:

The add-in system provides a smart search strategy to locate the installed add-ins. First, it searches for all .addin configuration files in the application AddIns directory and its sub directories. It is common to divide add-ins in separate sub directories to prevent file name collisions. The second step is the searching for the AddIns.xml file in the user profile directory. This file allows the deactivation of add-ins at user level and defining the location of external add-ins. The last step is to search in the user profile AddIns directory and sub directories for .addin configuration files. Concrete example directories are listed in Table 1.

Location Example Directory
Application AddIns C:\Program Files\SharpDevelop\2.1\AddIns
User Profile %AppData%\ICSharpCode\SharpDevelop2.1
%AppData% C:\User\Juergen\AppData\Roaming (Windows Vista)
Table 1: Example directories of the SharpDevelop add-ins.

Deployment

The add-in system simplifies the deployment of add-ins. The installation process consists of copying the add-in files to one of the special AddIns directories. It is not necessary to modify the program configuration. Uninstalling is done by removing the add-in files. A limitation of the add-in system is that the deployment tasks (install, update and uninstall) require a restart of the application.

Add-In Tree

The add-ins are able to extend each other. For example an add-in can extend a toolbar which is hosted by another add-in. SharpDevelop uses a tree structure to manage the extension points [Grunwald06]. The access of a concrete extension point is done via a path (e.g. /SharpDevelop/Browser/Toolbar). A path contains nodes and optional sub nodes. The nodes define the behavior of the extension point. The most simple node type is Class. This node type is responsible for creating an instance of a defined class by invocation of the parameter-less constructor. Other node types are responsible for creating UI elements or defining file filters for the OpenFileDialog or SaveFileDialog. These are the node types supported by the core. Further node types can be added by add-ins. The nodes are represented by the Codon class which delegates the object creation process to a Doozer. The Doozer class represents the node type and thus, it implements the behavior of a node.

The extensions are declared in the .addin configuration file. This strategy is chosen because the philosophy of the SharpDevelop developer team is to extract as much data into XML files as possible [HKS03, p. 28]. An advantage of this approach is the lazy loading of the add-ins. The .addin configuration files are read during application start-up whereas the add-in assemblies are first loaded when one of their extension points is accessed.

Service Locator

The add-in tree can be seen as a configurable factory. One drawback of core implementation is that different add-ins cannot share the same instance of a component which is defined in the .addin configuration. Nevertheless, the add-in tree is extensible and an implementation of the Service Locator pattern on the top of it is simple. Listing 7 shows a SingletonDoozer that creates only one instance of the object specified in the .addin file. The SingletonDoozer is registered at the AddInTree which is a static class (Listing 8). Listing 9 shows an extract of an .addin file that defines a MovieFinder component. The xml element Singleton refers to the SingletonDoozer instance. If the component is retrieved by any add-in, the SingletonDoozer is responsible to return an instance of the MovieFinder component (Listing 10). A limitation of this implementation is that the shared component needs a default constructor.

 1  public class SingletonDoozer : IDoozer
 2  {
 3    private Dictionary<string, object> instances =
 4      new Dictionary<string,object>();
 5 
 6    public bool HandleConditions
 7    {
 8      get { return false; }
 9    }
10 
11    public object BuildItem(object caller, Codon codon, ArrayList subItems)
12    {
13      string key = codon.Properties["id"];
14 
15      if (!instances.ContainsKey(key))
16      {
17        instances.Add(key,
18          codon.AddIn.CreateObject(codon.Properties["class"]));
19      }
20 
21      return instances[key];
22    }
23  }

Listing 7: A simple implementation for a SingletonDoozer.

 1  AddInTree.Doozers.Add("Singleton", new SingletonDoozer());

Listing 8: Registration of the SingletonDoozer.

 1  <Path name="/Service">
 2    <Singleton id="MovieFinder" class="MovieFinder.MovieFinder"/>
 3  </Path>

Listing 9: Define a component in the .addin file.

 1  movieFinder = AddInTree.GetTreeNode("/Service")
 2    .BuildChildItem("MovieFinder", null, null) as IMovieFinder;

Listing 10: Retrieve the MovieFinder component.

Conditions

Every tree node can contain conditions to indicate whether the node should be active. This is useful for dynamic changes of the nodes. For example, the predefined condition WindowsActiveCondition can be used to ensure that a toolbar button is only enabled if the editor window is active. The conditions are declared in the .addin configuration file.

Framework

SharpDevelop is not primary designed to be a framework for building own applications. Even though, the developer team state that the core can be used for other Windows-based applications. Especially the add-in system would help to build an extensible application.

(…) presents the AddIn architecture used in the IDE SharpDevelop, and how you can use it in your own Windows applications [Grunwald06].
It is possible to build a completely different application on top of the AddIn tree by just putting other Run commands in the tree. This application can then benefit from the AddIn tree, just as SharpDevelop does [HKS03, p. 56].

It is also possible to use more than only the core of SharpDevelop. Though, some code has to be changed for the own needs. Changing of the code has the disadvantage that it would be incompatible with the maintained code by the SharpDevelop team.

License

The source code of Sharp Develop is licensed under the GNU LGPL 2.19. Thus, it is an OSI Certified Open Source Software. The license is comparable to the Apache License, Version 2.0 but they are not compatible because of the different dealing with patents [FSF07].

8 The official Website of SharpDevelop: http://icsharpcode.net/OpenSource/SD.

9 GNU LGPL, Version 2.1. See http://www.gnu.org/licenses/lgpl.html.