Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Plug-in Architecture To Work for Multiple Platforms/Techs

4.44/5 (5 votes)
2 Aug 2015CPOL8 min read 35.8K   421  
Plug-in Architecture To Work in WinForms MVC + WPF MVVM + ASP.NET MVC + Mobile (Xamarin MVC/PhoneGap MVC) + Win 10 Universal App MVC

Introduction

Plug-in Architecture To Work in WinForms MVC + WPF MVVM + ASP.Net MVC + Mobile (Xamarin MVC/PhoneGap MVC) + Win 10 Universal App MVC

This is my attempt to implement a general plugin system to work in multiple platforms and multiple technologies, with the main intent is to increase shared projects to the max, over those platforms.

This is the first draft, and I will be going back and forth in it, while I implement it, till it gets fully functional, so it might change while it gets implemented.

Background

I searched the internet to find a suitable plug-in architecture that’s general enough and not too complex, to work with multiple technologies/platforms, mainly:

  • WinForms MVC
  • WPF MVVM
  • ASP.NET MVC
  • Mobile (Xamarin/PhoneGap) MVC
  • Win 10 Universal App MVC

As can be seen in these articles:

And after a lot of reading for several days, I decided to go with my own architecture. And decided to make it as an article in my blog and in CodeProject, and later on, in github.com, for sharing and collaboration with the community, to perfect it, and make it general enough for all, and to increase the sharing and benefit from the larger more beautiful minds out there, so please comment.

Reference Article

Objectives

I quote what MSDN said about the need for a Plug-in system:

  • To extend an application's functionality without the need to re-compile and distribute it to customers.
  • To add functionality without requiring access to the original source code.
  • The business rules for the application change frequently or new rules are added frequently.

And I add my own:

  • Faster compilation time and smaller solutions as each plug-in will need only small number of references to other projects.
  • Maximize reuse of the main business functionality over multiple UI/OS- platforms Technologies.
  • Simplify each project, to the maximum extent.
  • Help fellow developers to speed development on all platforms.

Technologies Used

The Main Architecture

Image 1

Code Packages/Classes

So here are the main pieces, and their main objectives:

Project: PlugInManager

This is the main project that will configure the main App Services:

  • ILogger
  • IExceptionHandler
  • IMsgBox
  • ILingual

And then, it will parse the plug-in folders:

App
    |-_Plug-ins
                |-            ASP.NET MVC
                |-            Mobile_Xamarin
                |-            Mobile_PhoneGap
                |-            Win 10 Universal App
                |-            WinForms
                |-            WPF

Depending on the configuration/LocalDB file property:

  • App_Platform: (WinForms, WPF, ASP.NET MVC, Mobile (Xamarin/PhoneGap), Win 10 Universal App)

It will get the .dll plugin for the main UI “IMainForm”, that is set in the configuration/LocalDB:

"WinForms"_ MainUI: MainFormplugin.dll

And get from it the main form, and show it.

Then it will search for the Authentication plugin, that is set in the configuration/LocalDB:

"WinForms"_Authentication: SimpleUserPasswordAuthenticationPlugin.dll

And get from it the ILoginForm, and show it to the user.

And will search for .dlls that have a reference to IPlugin, and create an instance of it, and pass to it the services, and call its “init” function.

It will have a service locater to find in all the plugins the required implementation of interfaces.

It will connect the DBObjects, to the LocalDB/ServerDB to get the list of IForms to be given to IMainForm, to show them, and to get all the IComposable List, to know which IForm they will be composed in.

Interface: IPlugin

Will have properties for the services, to be set by its constructor.

init” function, to make its internal unity container, fill itself with all classes inside the plug-in, from a utility class.

Plugin\WinForms\MainUI \ MainForm

Will get the names of the IForm list from the “Host”, which is the “PluginManager”, and show them to the user, for my WinForms, they will be shown in a TreeList or GridList, and only get what the user is allowed to see, depending on the IAuthentication implementation.

On double clicking the name of the IForm record, it will be sent to an activator, inside the IAuthentication, to see if its authorized, and show it to the user.

If anything will need a msgbox to be displayed, then it will be supplied by this plugin, by having an implementation to IMsgBox, and setting it in the Host.Container.

Plugin\WinForms\MainUI \ MsgBox

This will implement the IMsgBox interface that will be implemented by each platform, but in this specific plugin, it will be implemented for WinForms, which might be different all together in other platforms.

Services\DBLocal Previously DBInstance

There will be a local database (PCs SQL Server LocalDB, Mobile à SQLite), that will hold configurations per platform, maybe some/all error messages, and some caching.

Services\Logger

The logger project will implement ILogger interface, and gets injected to all plugins, this will make them free from referencing its library or CodeProject.

I am making it, use Enterprise Library Logging block: https://entlib.codeplex.com

Reason: Because of its good pluggable nature and multi platform support, and its configuration possibilities.

Services\ExceptionHandler

This project is for handling all exceptions at the UI plugins level, it will be responsible for formulating error/warning messages, and displaying them to the user, by giving it to the IFormError that will be supplied by the “MainUIPlugin”, which might be a WinForm/ASP.NET MVC/Xamarin/….

Services\Validation

This will have validations for general datatypes like int, double, decimal, date, time, or for logical types like email, …

And it will take validation from plugins, that implement IValidationPlug, e.g., JSValidation for validating JavaScript at ASP.NET client side.

Plugin\Services\English Lingual

This will supply English lingual translation for UI controls and also Data, by implementing ILingual, and there will be a configuration property to set the main language, and for each user, there will be [Main language/Secondary language] in his settings.

Configuration.Lingual= English Lingual Plugin.dll

UserA. Configuration.Lingual_Main= English Lingual Plugin.dll
UserA. Configuration.Lingual_Secondary= French Lingual Plugin.dll
Plugin\Services\ Authentication \SimpleUserAuthentication

This will implement the IAuthentication and IPrivilegeAccess for login checking, and checking for user access privileges, as this can be changed with other types of Authentications like “RoleAuthentication”, by setting a wide application configuration property:

Configuration.AuthenticationScheme: SimpleUserAuthentication.dll
Services\Object Management: UIFormViewManager

This will manage All forms/Views, which are the screen UI elements in all UI plugins, in several ways, like opening them, configuring their Combo boxes or List Boxes, showing detail/list of their data, extra. [to be further detailed]

Services\Object Management\ UIComposableManager

This will have all composable controls/subview, that will be inserted in Forms.

Services\Object Management\ObserverManager

Currently not well defined, thinking of making it use Rx observable/publisher style for registering/unregistering of events generated from UI/Domain objects.

Services\Object Management\CommandManager

Currently not well defined, thinking of making it offer executable commands for UI/Domain objects.

Services\Object Management\POCOManager

This will have all information about the POCO properties and their types, and linkes to other POCOs, maybe validations.

Layers

Image 2

The Layers from POCO classes to UI classes

These will implement the MVC pattern/Repository pattern.

POCO classes

This will have the business classes, and they will inherit from the Repository.Pattern.Ef6.Entity class, which implements the IObjectState interface for managing the POCO object state, and will all implement the INotifyPropertyChanged, so it will notify who uses it, of any internal changes, and IValidatableObject for making the POCO validate itself, by calling a method in the “Validation” project, that will search the DB for that POCO validations and uses them to validate it.

Where each main category will have its own project, like PersonPOCO, InvoicePOCO.

DAL Layer

This will have the mapping for the Entity framework 7 configurations of all POCO classes.

Where each main category will have its own project, like PersonDAL, InvoiceDAL.

Repository Layer

This will be the mediator between using Linq on the DAL layer, and upper layers, so it will hide the implementation details from them.

Where each main category will have its own project, like: PersonRepository, InvoiceRepository.

As seen here:

Model Layer/Controller Layer

I will ease things up, and relate to:

View Layer

This will be implemented in plug-ins, so we can have the app work in multiple platforms like Plugin\WinForms\PersonUI, InvoiceUI.

DBServer

Currently, I am thinking of using SQL Server, for app persistence.

Directory Structure

The directory structure of the architecture is as shown below:

Image 3

Future Update

Code will be published here and in github.com.

Points of Interest

  • Further study and comments are welcome.
  • Comments/Ideas/Fixes in all the above are welcome.
  • And other things to brain storm are:
    • Event engine/Observer Engine/Rx Engine
    • An engine that will facilitate plug-ability in actions and events in all or most layers.

There are the following questions that I need to have answers for:

Q1: Should I use GUID as primary key for some tables, to minimize conflicts when upgrading to new versions?

My answers to some questions asked:

Other Q1: Why not use MEF?

A1: I prefer to have all my classes in their pure POCO style, and not adorn them with specifics of other tools like MEF, so that's why I am using a DI-IoC container, to manipulate them from outside, not from inside.

History

  • v0.5.1: Tried to fix the pictures of the article + added "Other Q1"
  • v0.5: Created the main architecture

License

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