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
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 DBObject
s, to the LocalDB
/ServerDB
to get the list of IForm
s 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
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:
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