1. Today I finally announced Mono.Addins, a generic framework for implementing extensible applications in Mono.

    I've been maintaining the MonoDevelop add-in engine for almost two years now. This engine is based on the SharpDevelop add-in engine, which took ideas from Eclipse. At some point I decided that it would be interesting to be able to reuse the engine in other applications, so I decided to take it out of MD, move it to an independent library and make it more generic. That became Mono.Addins.

    This is the list of features of Mono.Addins taken from the announcement:
    • Supports descriptions of add-ins using custom attributes (for simple and common extensions) or using an xml manifest (for more complex extensibility needs).
    • Support for add-in hierarchies, where add-ins may depend on other add-ins.
    • Lazy loading of add-ins.
    • Provides an API for accessing to add-in descriptions, which will allow building development and documentation tools for handling add-ins.
    • Dynamic activation / deactivation of add-ins at run time.
    • Allows sharing add-in registries between applications, and defining arbitrary add-in locations.
    • Allows implementing extensible libraries.
    • In addition to the basic add-in engine, it provides a Setup library to be used by applications which want to offer basic add-in management features to users, such as enabling/disabling add-ins, or installing add-ins from on-line repositories.
    Reusing an add-in engine has many advantages. It's not only about reusing the library, but it also allows reusing an add-in model. Developers will be able to reuse knowledge and development tools to develop add-ins for different applications. Mono.Addins is specially good for this because it encourages self-documentation of add-ins, and it provides an object model for reading add-in descriptions, so building documentation and development tools based on it will be easy.

    However, creating an add-in engine that fits all application needs is not trivial. Different applications will have different extensibility needs. For example, in MonoDevelop some add-ins need to extend other add-ins, so add-in identity and versioning is an issue to take into account. Lazy loading of add-ins is also important, since and IDE may integrate many tools, but not all of them are needed at the same time. MD also needs to provide complex extension points, such as the solution tree pad, build pipelines or hierarchical menus. MD describes those extension points using XML manifests.

    Other more simple applications will have more simple needs. For example, an application may just need to load types from some assemblies copied to some directory. Mono.Addins can also be used in this case without adding development complexity. Instead of using XML manifests, extensions can also be declared using custom attributes, and there is no need to assign identifiers or versions to add-ins, since there won't be add-ins extending other add-ins.

    What's interesting is that both applications will be using the same add-in model, and it will be possible to use the same API, documentation and development tools for both cases.

    I'd like Mono.Addins to set an standard for building extensible applications in Mono. That's why I'd like to get feedback from applications developers about the library and about add-in development in general. I created a mailing list to collect this feedback: http://groups.google.com/group/mono-addins. If you are developing an application which can be extended by add-ins, please take a look at Mono.Addins and say something!

    To know more about Mono.Addins you can read the Introduction to Mono.Addins.
    A more detailed guide on using the library can be found here.
    And the source code is here.

    Enjoy!
    4

    View comments

  2. Just like last year MonoDevelop is participating in the Google Summer of Code as part of the Mono project. If you are a student, don't miss the chance of working on a very nice IDE for GNOME, and get paid for it! There are some project suggestions here, although fresh ideas are also welcome.
    2

    View comments

  3. If you open the View menu in MonoDevelop you'll find listed there two pads which look very similar: "Properties" and "Widget Properties", and you'll also find "Toolbox" and "Widget Palette". The reason for this duplication is that there are two designer models in the IDE: the Stetic model used by the GTK# designer, and the System.Component based model used by the ASP.NET add-in. Today I decided put an end to this duplication, and I started integrating those pads into a single Properties/Toolbox pair.

    The System.Component based toolbox is actually not so System.Component dependent. There is a MonoDevelop.DesignerSupport add-in which implements the property and toolbox pads, and which is designed to be pluggable, so I only had extend it from the GTK# designer. After some fixes and improvements I've been able to show the GTK widgets in the toolbox, and to drag&drop them in the designer. It's almost 100% functional now, there are only some small issues to fix, such as the order in which components are shown. But not too much...

    Integrating the properties pads has been a bit more tricky. I wanted the properties pad to be very generic and usable not only for visual designers, but also for the IDE in general. So for example if you select a file in the solution pad you would see the properties of the file.

    The first problem about the integration is that the Stetic model and the System.Component model are very different. In particular, properties of Stetic components are defined in class descriptors (specified in an xml file), while System.Component model is purely reflection based. Since it's not trivial to implement a property grid which can support both models, the solution has been to completely replace the properties grid depending on what has the focus. When the focus is in the GTK# designer, the properties pad will show the Stetic property grid, and when clicking on the solution pad, it will show the standard System.Component model property grid. We still have two property viewers, but now we have only one properties pad.

    The second problem to be solved, is how to detect that the currently selected object has changed, and that the properties pad has to be updated to show the properties of the new selection. In Stetic it is done by tracking focus change events, but it won't work as a generic solution, because the "currently selected object" can be *anything*, not only widgets. For example, the properties pad should change when the selection in the solution tree changes. So I decided to go for a pull model like the one used by the command manager for updating command status. Status of commands is checked periodically by getting the widget that has the focus. If that widget has a handler for the command, it is executed. If not, the command manager looks for a handler in a route of objects which starts on the active widget. This route is by default the chain parents of the widget, but it can be altered. For example, the solution pad re-routes commands to tree extensions before re-routing back to the parent. In this way node extensions have a chance to provide custom behavior for commands.

    How is all this related to the properties pad? Well, I'm using the same command target infrastructure to find a potential target object for the properties pad. So, any class in the command route can now not only handle commands, but also provide the "selected object" to be shown in the pad (it only needs to implement the IPropertyPadProvider interface and specifically the GetSelectedComponent() method). I quickly managed to implement a solution pad extension which implements that interface and returns the current tree selection. The result is what you can see in this screenshot:



    That is, by selecting any item in the tree, it will show its properties in the properties pad. It still needs a lot of polishing since some properties need to be hidden (it can be done by applying System.ComponentModel attributes), and the properties grid itself is not very stable, but it's looking nice.
    2

    View comments

Blog Archive
About Me
About Me
My complete name is Lluis Sanchez Gual, and I work as a developer for Novell. I'm part of the Mono team, and I'm leading the MonoDevelop project, a very exciting open source IDE for GNOME.
Loading