Implementation and Analysis of the. Net plug-in framework (I)

Source: Internet
Author: User

At the same time as starting your own system, you always want to make the system more flexible, so that others can be easily involved. This requires a complete plug-in system, today, I am going to write an article in the plug-in framework series, mainly to record the results of my study of the ScrewTurn Wiki system, which is also convenient for anyone who needs it.

 


I personally feel that the plug-in framework of the ScrewTurn Wiki system is quite well done, so that the plug-in makers can easily integrate the system, so this time is being studied. Let's talk about the architecture and requirements of the next plug-in framework. In my opinion, a plug-in system should be independent from the existing system class libraries, so that third-party developers can reference only the DLL of a plug-in project to complete all relevant development, in addition, there must be a certain and Unified Agreement on the system framework, so third-party developers cannot choose how to design the framework. Therefore, the general plug-in framework is better implemented by interfaces, the following describes the general call process. I will not draw a flowchart (I am too lazy to install it). I just need to explain it in text:

 


When a user accesses a website, the user calls the core function and calls the interface that implements the core function.

 


Therefore, by implementing different interfaces, you can easily implement different functional functions and achieve the effects of implementing different plug-ins. This principle is very simple, as long as someone has been familiar with OO, but how can we implement it? The following describes how to implement it. This plug-in framework mainly uses the interface + Provider mode for implementation. Therefore, you must first design the interface to be implemented. The following uses a formatting function as an example, this formatting plug-in is mainly used to format the content after the article is published. For example, you can create code highlighting plug-ins and viewing times plug-ins, you can call different formatting plug-ins to process the output. OK. In the first step, we first define a global IProvider interface so that all plug-ins can perform the following operations based on these interfaces:

 


IProvider. cs file:


Code
Namespace CoderBlog. PluginFramework
{
Public interface IProvider
{
/// <Summary>
/// Initialize the plug-in
/// </Summary>
/// <Param name = "host"> main system object, which allows the plug-in to call methods in the main system for decoupling </param>
/// <Param name = "config"> plug-in configuration file </param>
Void Init (IHost host, string config );

/// <Summary>
/// Called when plug-in is canceled
/// </Summary>
Void Shutdown ();

/// <Summary>
/// Plug-in developer information
/// </Summary>
PluginInfo Information {get ;}

/// <Summary>
/// Plug-in help information
/// </Summary>
String ConfigHelpHtml {get ;}
}
}

 

Because this is the most basic interface class, the methods included are the most usable, and each type of plug-in should be used. Here, by the way, I will mention the IHost interface, which is the interface called by the main system function. You can place some common methods that need to be used in the plug-in system and obtain the functions of the system configuration system, below I only provide two interfaces for demonstration. You can design them as needed. Therefore, the interface is not the focus of the system. The Code is as follows:

IHost. cs file:

Code
Namespace CoderBlog. PluginFramework
{
/// <Summary>
/// You only need to provide common functions and configuration information.
/// </Summary>
Public interface IHost
{
/// <Summary>
/// Obtain the user list
/// </Summary>
/// <Returns> </returns>
List <UserInfo> GetUsers ();

/// <Summary>
/// Obtain the plug-in provider configuration file
/// </Summary>
/// <Param name = "providerTypeName"> plug-in type name </param>
/// <Returns> </returns>
String GetProviderConfiguration (string providerTypeName );
}
}
 


Next, we will design a plug-in interface for Text Formatting. This interface will inherit the above base class interface (all types of plug-ins should be inherited from IProvider ).

To format the current output content, you also need to let the plug-in developer know the current context to facilitate the call of the required information. If you want to be more flexible, you can add an enumeration of Formatting Objects to specify which part of the information is only formatted by the current plug-in. Therefore, you must first create a FormattingContext enumeration and a ContextInfo class to pass the required information. the cs file contains the above two classes:

ContextInfo. cs file:

Code
Namespace CoderBlog. PluginFramework
{
Public class ContextInfo
{
/// <Summary>
/// Contains the required page context information
/// </Summary>
Public class ContextInfo
{
Private FormattingContext context;
Private HttpContext httpContext;
Private string username;

/// <Summary>
/// Initialize the context object required for formatting the object
/// </Summary>
/// <Param name = "context"> Format enumeration objects </param>
/// <Param name = "httpContext"> current http context </param>
/// <Param name = "username"> current user name </param>
Public ContextInfo (FormattingContext context,
HttpContext httpContext, string username)
{
This. context = context;

This. httpContext = httpContext;
This. username = username;
}

/// <Summary>
/// Obtain the currently formatted enumerated object
/// </Summary>
Public FormattingContext FormatContext
{
Get {return context ;}
}

/// <Summary>
/// Obtain the current http Context
/// </Summary>
Public HttpContext
{
Get {return httpContext ;}
}

/// <Summary>
/// Obtain the current user name
/// </Summary>
Public string Username
{
Get {return username ;}
}
}

/// <Summary>
/// Format enumeration to specify the part of the information to be formatted
/// </Summary>
Public enum FormattingContext
{
/// <Summary>
/// Sidebar
/// </Summary>
Sidebar,
/// <Summary>
/// Post title
/// </Summary>
PostTitle,
/// <Summary>
/// Post content
/// </Summary>
PostContent,
/// <Summary>
/// Page header
/// </Summary>
PageHeader,
/// <Summary>
/// At the bottom of the page
/// </Summary>
PageFooter,
/// <Summary>
/// Unknown
/// </Summary>
Unknown
}
}
}
 

 

OK. Now we can create the IFormatterProvider interface:

IFormatterProvider. cs file:

Code
Namespace CoderBlog. PluginFramework
{
Public interface IFormatterProvider: IProvider
{
/// <Summary>
/// Format the specified content
/// </Summary>
/// <Param name = "content"> content to be formatted </param>
/// <Param name = "context"> current formatted object context </param>
/// <Returns> formatted content </returns>
String Format (string content, ContextInfo context );

/// <Summary>
/// Format the post title
/// </Summary>
/// <Param name = "title"> post title to be formatted </param>
/// <Param name = "context"> current formatted object context </param>
/// <Returns> formatted content </returns>
String FormatPostTitle (string title, ContextInfo context );

/// <Summary>
/// Format the content of the page header
/// </Summary>
/// <Param name = "head"> content of the page header to be formatted </param>
/// <Param name = "context"> current formatted object context </param>
/// <Returns> formatted content </returns>
String FormatPageHead (string head, ContextInfo context );

/// <Summary>
/// Format the bottom of the page
/// </Summary>
/// <Param name = "foot"> content at the bottom of the page to be formatted </param>
/// <Param name = "context"> current formatted object context </param>
/// <Returns> formatted content </returns>
String FormatPageFoot (string foot, ContextInfo context );

/// <Summary>
/// The execution priority of the formatting plug-in. This is important because when multiple formatting plug-ins are executed simultaneously,
/// Other formats may be overwritten, so there must be a priority issue
/// </Summary>
Int ExecutionPriority {get ;}
}
}
 


After this interface is designed, all future formatting-related plug-ins must implement this interface. Then, you can implement different interface methods to format the corresponding content according to the plug-in author's needs.

OK. Let's talk about this in this article. All the required interfaces are defined. The next article will explain how to implement related interfaces.

Author: "Winson's blog sky"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.