Plux.NET
A Dynamic Plug-in Platform for .NET


Plux.NET is a plug-in platform for extensible and customizable .NET applications. It supports dynamic composition of software, which allows developers to build applications in which users can load and integrate just those components which they need for their current work. With dynamic composition users can also reconfigure an application on the fly by dynamically swapping components.

Basic Concepts

Plux uses the metaphor of extensions, slots, and plugs (Fig. 1). A Plux application consists of an ultra-thin core as well as of extensions that can plug into slots of the core or into slots of other extensions at run time. A slot specifies a contract for extending a piece of software. An extension with a slot is called a host. An extension with a matching plug is called a contributor for this slot. In essence, a slot declares the kind of services a host expects and a contributor provides these services.

Fig. 1: Application core and extensions

A slot is defined by an interface and optionally a list of parameters with their names and types. A contributor extension provides a class implementing this interface as well as values for the parameters. The host extension will rely on these parameters to integrate the contributor. Extensions, slots, and plugs are specified using .NET attributes.

Let's assume that our host is a graphical menu that allows menu items to be installed as extensions (Fig. 2). It defines a slot »MenuItem« with an interface »IMenuItem« and two parameters: »Text« for the name of the menu item, and »Icon« for the icon to be used in the menu item. The contributor in this example provides a print menu item. The class »PrintItem« implements the required interface and provides values for the parameters: "Print" for the text parameter and "print.gif" for the icon parameter.

Fig. 2: Menu item slot and print item extension

For every slot, Plux detects available extensions, loads them, assigns the parameter values to the parameters and notifies the host that owns this slot. The host can then take actions for integrating the extension, e.g., by inserting a new menu item into its menus and connecting it to the contributor's object. Further details on metadata and composition in Plux can be found in Section 2 of the paper »Composing user-specific web applications from distributed plug-ins«.[11]

Current Status and Contributions

Over the past few years we developed the Plux framework, which comprises an infrastructure for desktop applications with dynamic plug-and-play composition. Recently, we extended Plux for web applications to support multiple users as well as distribution of plug-ins.

Composition infrastructure for desktop applications. Plux builds an application from plug-ins which are stored in a repository folder in the file system. It discovers the extensions from plug-in dll files and composes the application from them by connecting plugs to matching slots. If a user wants to add a feature, he drops a plug-in dll into the repository. Plux discovers the plug-in on the fly and integrates it into the application. Similarly, if the user wants to remove a feature, he removes the corresponding plug-in from the repository. The user can view the current composition state with the Plux visualizer tool. The visualizer shows the currently integrated extensions and their interconnections (Fig. 3). It also allows the user to reconfigure the application by plugging or unplugging extensions.

Fig. 3: Plux visualizer showing the Plux core extensions and the visualizer extension

Further details on the Plux composition infrastructure can be found in Section 3 of the paper »Composing user-specific web applications from distributed plug-ins«.[11]

Composition infrastructure for web applications. The web version of Plux allows developers to build distributed multi-user web applications. Multiple users can work with such a web application concurrently, extending it with different plug-ins that can even reside on different computers. For every user Plux maintains a separate composition state. A novel feature of Plux is that users can extend the web application with user-specific plug-ins that reside on the client computer. Such client-side plug-ins are seamlessly integrated with the plug-ins on the web server. Fig. 4 shows an example of a web application, namely a time recorder that consists of a TimeRecorder extension on the web server, a Clock extension on a clock computer and a Sync extension on the client computer.

Fig. 4: Time recorder application assembled from distributed plug-ins

Further details on the Plux composition infrastructure can be found in Section 4 of the paper »Composing user-specific web applications from distributed plug-ins«.[11]

Composition behaviors. By default, Plux fills every slot in the application with instances of all extensions that have a matching plug. As a novel concept, Plux allows developers to apply composition behaviors to customize the composition process without programming. For example, a composition behavior can control how many contributors are connected to a slot or it can ensure that a certain slot is only filled if some other slot has been filled before (Fig. 5). Plux provides predefined behaviors for common composition patterns, but developers can also define application-specific behaviors. Developers can control the composition of their application by applying these behaviors. The benefit of using declaratively specified behaviors instead of programming is that they can be reused, which leads to less programming overhead.

Fig. 5: A composition behavior can control the composition order. For example, it can specify that a certain slot is only filled after another slot has been filled.

Further details on composition behaviors can be found in the paper »Rule-based Composition Behaviors in Dynamic Plug-in Systems«.[10]

Templates. In Plux, components declare their provided and used services using .NET attributes. Plux connects the components based on these metadata. When developers need to reuse general-purpose components in different parts of an application, the metadata need to be different on each reuse. Therefore, Plux supports genericity with templates, i.e., the general-purpose components are defined as templates, and Plux generates customized components from these templates on demand. In order to generate components from the templates, metadata placeholders are replaced with metadata from external sources, e.g., from a configuration file or a database. Further details on templates can be found in the paper »Adding Genericity to a Plug-in Framework«.[8]

Composition rights and security restrictions. Plux applications allow third parties to contribute functionality. This can be a security issue. Thus, Plux allows application developers to restrict who is allowed to extend an application, at which points the application can be extended by a specific third party, and which operations such extensions are allowed to perform. The set of operations granted to a component can further be narrowed down depending on the services it uses.

Retrofitted security. Plux allows developers to retrofit security arround unsecured components. Developers can specify security constraints declaratively and Plux wires interceptors between the restricted components. Composition interceptors can block discovery, instantiation, usage, and provision of components. Method call interceptors can block calls to components and libraries, blank out return values and sanitize arguments, log and report component calls, and ask for elevated privileges. Retrofitted security lets users choose components by their functional features alone and add security separately.

Application snapshots. Dynamic reconfiguration allows users to tailor an application to a specific working situation. After a user has assembled a desired configuration in a plug-and-play manner, he can make a snapshot of this configuration in order to restore it later when a similar working situation arises.

Version resilience. A slot interface can change while an existing contributor still uses the old interface. Plux provides semi-automatically generated adapters for making such components compatible. Compatibility means that new hosts can use old contributors as well as old hosts can use new contributors. The same mechanism can even be used to adapt between components that provide interfaces which are incompatible per se (Fig. 6).

Fig. 6: A generated adapter is used to integrate two incompatible extensions.

Composability testing. Plux includes a composability test tool that checks if components support dynamic composition. In dynamically composed applications, the order of composition is undefined. If a component implicitly relies on a particular composition order, our testing tool will detect this defect, because it tries to integrate the contributors in every possible order. The tool also analyzes the test results to find possible causes of defects and makes suggestions how they can be corrected.

Fig. 7: Testing a component.

Further details on composability testing can be found in the paper »Testing the Composability of Plug-and-Play Components«.[9]

Composition debugger. Plux includes a trace-based debugger for dynamically composed applications. The debugger traces and records the composition while an applications is running. The developer can replay the recorded composition step by step in order to locate composability defects. The debugger is integrated with the Plux visualizer, i.e., while the composition replays, the visualizer shows the corresponding composition state.

Further Information

This work was funded by BMD Systemhaus and the Christian Doppler Research Association. It was performed in the Christian Doppler Laboratory for Automated Software Engineering.

Please note that this is a beta version of Plux. Modifications of features and programming interfaces may happen. The Plux executables are distributed "as is" and without any warranty or license. The sources are not (yet) published, and a license model for them is yet to be defined.

Publications

  1. Löberbauer, M.: Testing and Debugging of Dynamically Composed Applications. Dissertation, Johannes Kepler University, Linz, Austria, 2012.
  2. Löberbauer, M., Wolfinger, R., Jahn, M., Mössenböck, H.: Composition Mechanisms Classified by their Contributor Provision Characteristics. 8th IEEE International Symposium on Intelligent Systems and Informatics, SISY 2012, September 20-22, 2012, Subotica, Serbia (accepted for publication).
  3. Jahn, M., Rabiser, R., Grünbacher, P., Löberbauer, M., Wolfinger, R., Mössenböck, H.: Supporting Model Maintenance in Component-based Product Lines. Joint 10th Working IEEE/IFIP Conference on Software Architecture, WICSA 2012, August 20-24, 2012, Helsinki, Finland.
  4. Jahn, M., Löberbauer, M., Wolfinger, R., Mössenböck, H.: Plux.Net - A Dynamic Plug-in Platform for Desktop and Web Applications in .Net. Software-Technologien und -Prozesse, 3. Konferenz STeP 2012, Oldenbourg, 2012.
  5. Jahn, M., Wolfinger, R., Löberbauer, M., Mössenböck, H.: Composing User-specific Web Applications From Distributed Plug-ins. Computer Science - Research and Development, Springer, 2011.
  6. Jahn, M., Löberbauer, M., Wolfinger, R., Mössenböck, H.: Rule-based Composition Behaviors in Dynamic Plug-in Systems. 17th Asia Pacific Software Engineering Conference, APSEC 2010, November 30-December 3, 2010, Sydney, Australia.
  7. Löberbauer, M., Wolfinger, R., Jahn, M., Mössenböck, H.: Testing the Composability of Plug-and-Play Components. 8th IEEE International Symposium on Intelligent Systems and Informatics, SISY 2010, September 10-11, 2010, Subotica, Serbia.
  8. Wolfinger, R., Löberbauer, M., Jahn, M., Mössenböck, H.: Adding Genericity to a Plug-in Framework. 9th Intl. Conference on Generative Programming and Component Engineering, GPCE 2010, October 10-13, 2010, Eindhoven, Netherlands.
  9. Wolfinger, R.: Dynamic Application Composition with Plux.NET: Composition Model, Composition Infrastructure. Dissertation, Johannes Kepler University, Linz, Austria, 2010.
  10. Jahn, M., Wolfinger, R., Mössenböck, H.: Extending Web Applications with Client and Server Plug-ins. Software Engineering 2010, SE 2010, February 22-26, 2010, Paderborn, Germany (Best Paper Award).
  11. Rabiser, R., Wolfinger, R., Grünbacher, P.: Three-level Customization of Software Products Using a Product Line Approach. 42nd Hawaii International Conference on System Sciences, HICSS-42, Big Island, Hawaii, USA, January, 5-8, 2009.
  12. Wolfinger, R.: Plug-in Architecture and Design Guidelines for Customizable Enterprise Applications, OOPSLA 2008 Doctoral Symposium, OOPSLA 2008, Nashville, Tennessee, October, 19-23, 2008.
  13. Wolfinger, R., Reiter, S., Dhungana, D., Grünbacher, P., and Prähofer, H.: Supporting Runtime System Adaptation through Product Line Engineering and Plug-in Techniques. 7th IEEE International Conference on Composition-Based Software Systems, ICCBSS 2008, Madrid, Spain, February, 25-29, 2008 (Best Paper Award).
  14. Wolfinger, R., Prähofer, H.: Integration Models in a .NET Plug-in Framework. SE 2007 - the Conference on Software Engineering, Hamburg, Germany, March 27-30, 2007.
  15. Wolfinger, R., Dhungana, D., Prähofer, H., Mössenböck, H.: A Component Plug-in Architecture for the .NET Platform. Modular Programming Languages, Lightfoot, David; Szyperski, Clemens (Eds.), Lecture Notes in Computer Science , Vol. 4228, Proceedings of 7th Joint Modular Languages Conference, JMLC 2006, Oxford, UK, September 13-15, 2006.