Click here to Skip to main content
15,895,084 members
Articles / General Programming / Threads

Plugged.NET - An event based plug-in library for enterprise application integration and extensibility

Rate me:
Please Sign up or sign in to vote.
4.89/5 (19 votes)
25 Jul 2013CPOL6 min read 34.1K   1.4K   92  
An event based plug-in library for enterprise application integration, extensibility and cross business application management.
1. Introduction

Why do we need a plugin framework?

The need of time has pointed developers towards rapid component development and plug-n-play architechtures. The industry is looking towards enterprise product portfolio integration and/or some form of ESBs. I have heard several talks but indutrial king-pins thrying to prove apples as oranges (or atleast a new red color hard cousin of orange which can internally look and feel just like orange but gives so much more benefit). SUch thoughts, I agree, can either come from someone under severe conspitipation or from look-I-am-Einstein brains. But the arguments are also not entirely false. For product survival it has become very important to should adaptability and polymorphibility in as many places as possible. This is so much more true in case of small-to-mid size enterprises targetting small-to-mid-size market. 

Another very interesting business need is compartmentalizing multiple business logic processes, across physically diverse development groups and then integrate them in the same assembly line. Even in such context using a plugin mode of separation becomes important.

2. Background 

I've suffered (working) for several months in 'enterprise application-porfolio integration platforms' where everyone expects a plugin to be no less than Albus Dumbledore, I have learnt, rather in a hard way, to propose using a plugin management platform uniformly across multiple integratable applications. There is rather no compulsion to use it at the beginning, but as soon as you think of a plugin architechture, think of uniforming them.

This article is targetted at such requirements where it can give a quickstart towards plugin hosting, management and integration. By using such a framework, as a developer, you are only writing your custom BL and not bother to dirty your hand.

3. How does it work?

Event based plugin interaction/invocation.

Times have changed. Now a plugin is expected to be no less than a superhuman.

- It needs to understand host application gestures
- It needs to work in the background
- It needs to raise and subscribe to platform defined events
- It needs to change when a newer version needs to be deployed
- It needs to integrate with host of other invocation channels

So the article proposes the plugin to be event based. The plugin handshakes with the host platform during initialization. And such a handshake is composed of a mutual two-way subscription to the interesting events. This handshake would live until the plugin is living in the host scope/lifetime.
Certain initializations is still a simple invocation but these, in principle, could also be graduted to events. My personal take is, an event based communication is only necessary when its occurance (or its timeframe) is uncertain. Actions such as initialization is generally obvious and can be spared from the overhead from an event based invocation.
As spiderman said, "With power comes responsibility", I am too small an entity to prove it wrong. So here comes your responsibilities starting with using Dispatcher object when you use this (which mostly will be the case) in an UI intensive application(s).


Managed Extensibility Framework (MEF)

A bit fo a cakewalk and handwashing from the good old days' "dirty work". A good or great part of hosting plugins is to load them. A few years back developers had to jump, catch and yell (in short a circus effort) to reflectionalize object creation. And then there was MEF (http://mef.codeplex.com/). In short it helped to quickly nd dynamically wrap the plugin instance creating pain. With several other nifty utilities here this pne proved quite a blessing. Our PluginManager internally uses a factory here which serves as the heart of the entire system and the heart's first beat looks like this:

[CODE]

        public void Compose()
        {
            var catalog = new AggregateCatalog();
            catalog.Catalogs.Add(new DirectoryCatalog(extensionsPath));
            Directory.GetDirectories(extensionsPath).ToList().ForEach(path => catalog.Catalogs.Add(new DirectoryCatalog(path)));

            container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }

There are many things which comes free, one of the main ones is automatic dependency resolving from multiple disjoint probing paths.
The class is hidden behind a short interface (in case/if/when there is a day when MEF is runs obsolete)

[CODE]

    public interface IComposition<T>
    {
        void Compose();
        void Decompose();

        IEnumerable<T> ComposedItems { get; set; }
    }

With these serving as the boiler plate code the rest of the hosting code kicks off...


The Plugin Host

The term host is a little blown up here, may be a container would sound more appropriate. But again this does more than container. These few classes are responsible for:

- Load plugin assemblies (it can be configured 'from where' - I have used the users APPDATA folder)
- Serves as a one stop shop from standard application to plugin queries
- A sample WPF window is also added to demontrate the primary usage of the PluginPlatform. Please note that the sampleHost only does the bare minimum to load plugins. There are several other features to be explored (documented below).

Here are the two most important methods of the host:

[CODE]

        private bool RegisterPluginHandshake(IEnumerable<PluginInfo> plugins)
        {
            return pluginManager.RegisterExtensions(this, PluginNotifyMessage, GetUserContext(), plugins);
        }

        private void UnRegisterPluginHandshake(IEnumerable<PluginInfo> plugins)
        {
            pluginManager.UnLoadExtensions(this, PluginNotifyMessage, plugins);
        }


A little deeper into the Plugin Platform...

Here is a functional diagram of the scope of the platform. The mentioned interface names might differ in attached code. But it should be easy to determine which are the ones. Below is the interface that manages the event contract.

[IMAGE]

[CODE]

   public interface IApplicationEvents
   {
       // called when popup Application starts
       event EventHandler OnApplicationStart;

       // called when popup Application is closed
       event EventHandler OnApplicationClose;

       // called when the module is first time loaded
       event EventHandler OnModuleInitalize;

       // called when any module file action 
       event EventHandler OnFileSystemEvent;

       // called when any module action like show window
       event EventHandler OnActivateEvent;      

   }

    public interface IExtensionEvents
    {
        event EventHandler OnStarted;
        event EventHandler OnCompleted;
        event EventHandler OnError;
    }

It is important to note here that the application and the plugins both are event sources themselves. While the platform is free to decide what kind of a event it wants to be part of the domain, the plugins are limited to raise only those events that the platform has predecided to be listened by itself. This in no way should be understood as a heavyhanded decision or a medium to control. There could be a host of interesting events and all of them could be made available under multiple versions/releases. Please check the illustration below.

[IMAGE]


4. Using the code

The code in the framework is straight-forward and it is possible to just work with Common.plugin.Platform.dll (unless you need to change the framework or debug). Two basic plugins are included in the solution to get you started. 

KickStartPlugin - As stupid as the name could be it just listens to the right click context menu item event from windows explorer and responds with another parallel event. This happens through the singleton application instance (the code for which is included but beyond the scope of discussion in context with plugin integration)

TimeEventPlugin - Another equally stupid usecase. This plugin internally uses a timer to raise events every 10seconds to bog the application out (just for your interest).

Below is a normal screenshot of the application.

[IMAGE]


5. Applicability

To summarize the framework (or the idea) is targetted at 

- to publish your application and let independent softwares/teams create custom functionality to extend your application externally
- integrating multiple business processes in the same assembly line (if need be).
- manage complex development functions but segrating efforts and then merging the application under a container

6. What's next?

COM integration for third party COM app
Implicit authentication with logged-in or ActiveDirectory user

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Software Developer
India India
is a poor software developer and thinker. Presently working on a theory of "complementary perception". It's a work in progress.

Comments and Discussions