ASP.Net Core Plugin Manager

What is AspNetCore Plugin Manager

The plugin manager is an ASP.Net Core plugin manager which can be used to extend any Core website.

There are both built in extensions and the ability to add custom extensions. Built in extensions allow developers to quickly and easily add:

  • Middleware extensions.
  • Api controllers
  • Services for DI
  • Entire ASP.Net Core sub websites

Custom extensions allow a host application to extend it’s own interface, or expose inner workings that plugins can exploit, examples of which are:

  • Add menu items
  • Add buttons to a home page
  • Add marketing functionality in terms of rotating carousel images.
  • Customize internal web pages.

Supported Development Principles

Plugin technology is a nutural proponent to the SOLID principles of software development, each plugin has a single purpose and the host can be extended without being directly modified.

With each plugin having a single purpose, developers can focus on individual aspects of the entire project.

Benefits

Typically a software developer, or a team of developers within a software house will develop multiple solutions for many clients,
each of those solutions will have many shared aspects, such as:

  • Customer Management
  • Log in
  • Marketing
  • Product Display
  • Invoicing and Accounting
  • Product Management

By utilising plugin technology in conjunction with the DRY principle, time to live from conception to release can be dramatically
reduced. Whether it be adding a “Customer Management” plugin which is shared amongst many websites, to developing a single “Log In” plugin
which can also be shared between projects. Once a plugin has been developed and tested it can be deployed simply by being
loaded into the host application using the Plugin Manager.

There are many other benefits to using plugin technology within a website, they include:

  • Extendable. A website can be extended dynamically without recompiling or rebuilding the host site.
  • Paralell Development. Teams of developers can work on different aspects of the project, in paralell.
  • Reuse code. Once a plugin has been developed and tested, it can be re-utilised in other projects.
  • Quickly isolate and solve problems within a system.

How it works

The Plugin Manager exposes four static methods via the PluginManagerService class

  • Initialise. Initialises the Plugin Manager, loads all plugins.
  • Configure. Allows plugins to configure the request pipleine.
  • ConfigureServices. Allows plugins to add services to the host application.
  • GetPluginClasses. Retrieves an instance of class T from all plugins.

These four methods allow a host application to interact with all plugins.

The following image shows how the plugins relate to the host application.

PluginTechnology

Middleware Extensions

Middleware extensions are the pipeline used for requests in asp.net core. Each middleware plugin can process part or all of the request, and then either choose to return the result or pass on down to the next piece of middleware

Benefits of using Middleware Plugins

There are many uses for middleware within ASP.Net Core, a few examples are:

  • Add security headers
  • User session management
  • Extracting Marketing data

The list is as open as the developers mind.

UserSession Manager Example

Included in the sample source code is a UserSession Manager. This plugin is a Middleware extension that looks for an existing session, creates one if one does not already exist and then add’s it to the HttpContext for use in Controllers loaded into the application.

The UserSession is highly optimised and allows the developer to store custom information to identify each vistor to a website. If required GeoIp data can be attached to the UserSession class.

A variety of reporting options are available to make maximum use of the Seo data collected.

To access the user session within a controller, simply obtain a reference from the HttpContext instance.

using System;

using Microsoft.AspNetCore.Mvc;

using Shared.Classes;

namespace DemoWebsitePlugin.Controllers
{
public class ServicesController : Controller
{
public IActionResult Index()
{
UserSession session = (UserSession)HttpContext.Items["UserSession"];

if (String.IsNullOrEmpty(session.UserName))
{
// user is not logged in, do something...
}

return View();
}

public IActionResult Middleware()
{
return View();
}
}
}

Dependency Injection

ASP.NET Core supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies.

Plugin Manager fully supports this type of plugin, during the initialisaton phase individual plugins can register services via the IServiceCollection, which can then be used by the host application, or other plugins.

How it Works

This method is slightly different than the other native plugin types. We create a lightweight library who’s only purpose is to contain interfaces and/or abstract classes.

This library is referenced by the plugin which implements the interface or abstract class, and is also responsible for registering the interface with the IServiceCollection instance for the host application.

DependencyInjection

Example Memory Cache Plugin

The source control contains a sample plugin which implements an IMemoryCache object. The interface is registered within the SharedPluginFeatures library.

The plugin implements 3 methods:

  • GetShortCache. Returns a cache which has a default lifetime of 5 minutes.
  • GetCache. Returns a Cache which has a default lifetime of 2 hours.
  • ResetCaches. Clears all caches of all data.

Although their are default lifetimes, these can be overridden within appsettings.json.

When the class is initialised, it registers the IMemoryCache interface as a service for DI.


public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton();
}

Controllers can then get the IMemoryCache instance when being created, and take advantage of the IMemoryCache instance to add or get cached data.


public class HomeController : Controller
{
#region Private Members

private readonly IMemoryCache _memoryCache;

#endregion Private Members

#region Constructors

public HomeController(IMemoryCache memoryCache)
{
// Memory Cache is initialised during the Plugin Manager and set to be injected in using DI
_memoryCache = memoryCache ?? throw new ArgumentNullException(nameof(memoryCache));
}

#endregion Constructors
}

Api Controller

If you have Api Controllers for RESTful Http services, these too can be plugged into the host application. Develop the Api services you require and then plugin them in to the host application.

Benefits

An Api Web service could easily be split into compartmental pieces, allowing for easier development, testing and integration.

Multiple versions of the Api could be loaded simultaneously and deprecated by disabling the plugin within appsettings.json

Plugin Website

A website is usually a collection of multiple types of content and services, these could be in the form of:

  • A Shopping Cart
  • Product Display
  • Services Offered
  • Customer/Member area
    • Invoicing
    • Orders
    • Billing/Shipping Addresses
    • Licences
    • Downloads
  • Payment Gateways
    • Card Payment Provider
    • Paypal
    • Cheque/Postal Order
  • Management/Admin Interface
    • Cusotomer Management
    • Order Dispatch
    • Stock Management

Each of these custom elements are systems within their own rights and can be loaded as plugins.

Advantages

Each section or sub section of a website can be developed and tested in isolation.

Specific elements can be shared as plugins, between different customer websites, supporting the DRY pinciple.

How it Works

A sub system is developed using ASP.Net Core, and pre-defined routing agreed upon, this routing will ensure a system works together when all the pieces are plugged in.

The resources required by the project can either be embedded in, or deployed seperately. Plugin Manager supports either method.

If for instance you have a design team which creates the themes the views for each customer, these can be developed as part of the main host project. Alternatively the views, css, images and JScript files can be embedded into the plugin website. Plugin Manager will extract all resources where required, however, appsettings.json can be configured so that resources are not overridden.

Embedded Resources

To embed resources, these being .cshtml files, images, css or script etc, right click the item in the solution explorer, select properties and choose Embedded Resource as the build action.

EmbeddedResources

The resources are then extracted by the plugin manager, into the correct path for use when required

Custom Plugins

Custom plugins are the most flexble of all, they allow developers to extend a host interface, with minimum of ease.

There are a multitude of uses for extending an interface, for instance you could have a menu system which is dynamically populated depending on the plugins that are loaded.

Another use would be to display carousel items depending on active marketing campaigns, the list is literally as open as the website being developed.

How it Works

A custom plugin is individual to the host application, a single requirement is a shared library of Interfaces and abstract classes, that can be loaded by the host application. Plugins provide the implementation to the interface or abstract methods and the host application is responsible for extending the interface.

CustomPlugin

Example

In this example, the host application exposes an abstract MenuItem class, which is overridden in plugins.


namespace SharedPluginFeatures
{
public abstract class MainMenuItem
{
public abstract string Area();

public abstract string Controller();

public abstract string Action();

public abstract string Name();
}
}

A plugin can create as many MenuItems as it requires, by overriding the MainMenuItem class


public class MiddlewareMenuItem : SharedPluginFeatures.MainMenuItem
{
public override string Area()
{
return String.Empty;
}

public override string Controller()
{
return "Services";
}

public override string Action()
{
return "Middleware";
}

public override string Name()
{
return "Middleware";
}
}

When loading the layout page, the host application can query all plugins for MainMenuItem classes, and receive instantiated classes.

code

ASPNetore.PluginManager is available under GNU General Public License v3.0

Source code is available from GitHub.com

Nuget Package

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s