In the ApplicationProgramDuring the development process, many modules are repeatedly developed, so we began to collect data and design and develop the plug-in system framework. The framework is used to integrate various sub- ins.
Design Phase 1: Define an interface as a separate Assembly so that the plug-in can implement this interface. The framework uses reflection to read the sub-plug-in function.
Problem:
1. Define several interfaces.
2. The changes to existing modules are too large.
Design Phase 2: focus on solving the second problem in the first phase, and add an adapter between the Protocol interface and plug-in. With this structure, the existing modules can be easily integrated with the host framework.
Design Phase 3: inspired by phase 2, the interface should be defined in advance in phase 1. Improved by adding an adaptation tool between the interface protocol and the host framework to disconnect the interface protocol from host development.
Problem: the plug-in is highly compatible with the Protocol and the host-protocol. Adapter operation is troublesome.
Phase 4: complete framework: basically, the plug-in and the host itself implement predefined interfaces (Views) in phase 3. Through this framework design, the host system and plug-ins can be developed without interfering with each other (to facilitate later integration, plug-ins and host development are defined as interfaces ), after the development, you only need to add an interface protocol and two-person adapter to complete host and plug-in integration.
Plug-in to obtain Master Program Data
Solution Group |
Project name |
Description |
Contract |
Codemarks. Framework. plugin. Contract |
Inter-assembly Protocol |
|
|
|
Addin side |
Codemarks. Framework. plugin. View. User |
Plug-in function interface definition |
Addin side |
Codemarks. Framework. plugin. Adapter. User |
Plug-in Adapter |
Addin side |
Codemarks. Framework. plugin. addin. User |
Implementation of user plug-ins |
Addin side |
Codemarks. Framework. plugin. addin. Model |
Host operation implementation class |
|
|
|
Host side |
Codemarks. Framework. plugin. Host. View. User |
Host function interface definition |
Host side |
Codemarks. Framework. plugin. Host. Adapter. User |
Host protocol adapter |
Host side |
Codemarks. Framework. plugin. Host. User |
Implementation of user plug-ins |
Host side |
Codemarks. Framework. plugin. Host. Model |
User plug-in Entity () |
|
|
|
In this plug-in framework, the main problem solved is that the host and plug-ins communicate with each other. For example, the log plug-in verifies that the user has the permission to publish data, the log plug-in does not directly access the user center plug-in, but requests () from the host. After receiving the request, the host will call the user center plug-in to complete the functions requested by the log plug-in. There are two main operations in the data communication between the plug-in and the Host:
1. The host obtains plug-in data. For example, the log requests the user to request user permission data.
2. The plug-in obtains host data. If the log plug-in requests user data, the host will create a user object through reflection and return it to the log plug-in.
Host plug-in Diagram
Log plug-in requests user data
Project Analysis:
Contract Project:
Define the interaction protocol between the plug-in and the host in advance, and define two interfaces: iusercontract iuserinfo (entity class,
Iusercontract inherits from the icontract reserved interface (responsible for plug-in program lifecycle and permission related interfaces)
Iusercontract interface definition method Add User Method
Bool adduser (iuserinfo userinfo) iuserinfo
Getuserinfobyname (string username );
Addin Sider Structure
The plug-in program only needs to implement the methods defined in the Protocol, so that the communication between the host and the plug-in can be adapted. To facilitate later integration, we first define interfaces for the functions of the plug-in system, 1 2 3 the project does not have any relationship with coroutine.
1 |
addin side |
codemarks. Framework. plugin. View. User |
User plug-in function interface definition |
2 |
addin side |
codemarks. Framework. plugin. addin. User |
specific implementation of the user plug-in class |
3 |
addin side |
codemarks. Framework. plugin. addin. Model |
host operation implementation class |
4 |
addin side |
codemarks. Framework. plugin. Adapter. User |
plug-in adapter |
// Custom object class in the plug-in
// Functional interfaces in the userview plug-in
// Specific implementation of the userview interface in the user part
AboveCodeThe independent code is irrelevant to the interface protocol.
// The adduser (iuserinfo) and getuserinfobyname () in the API Protocol iusercontract are implemented by the adapter ();
An iuserinfo interface is passed in when a host request is sent to add a user. The type of the customuserinfo parameter required by the user plug-in is different. The returned value in getuserinfobyname (string username) is icustomuserinfo, in the adapter class, convert customuserinfo to userinfo and convert userinfo to customuserinfo.
Public interface userview
{
Customuserinfo getuserinfobyname (string username );
Int adduser (customuserinfo userinfo );
}
// The plugin implementation class is converted to the Protocol Class
Define customuserinfotocontractadapter implementation Interface Protocol iuserinfo Interface
Define private customuserinfo addin; assign values through the construction function, and return addin. name in the name get attribute;
The same is true for the set method.
/// <Summary>
/// Convert from custom entity to Protocol
/// </Summary>
Internal class customuserinfotocontractadapter: iuserinfo
{
Private customuserinfo addin;
Public customuserinfotocontractadapter (customuserinfo)
{
This. addin = customuserinfo;
}
# Region iuserinfo Member
Public string name
{Get {return addin. Name ;}
Set {}
}
... Other attributes
# Endregion
}
// The plugin implementation class is converted to the Protocol Class
Define contracttcustomuserinfoadapter to inherit from customuserinfo of the plug-in Entity class, and define private iuserinfo contract; assign values to contract using constructors, and return contract. Name When the name get attribute is called;
Internal class contracttocuntomuserinfoadapter: customuserinfo
{
Private iuserinfo contract;
Public contracttocuntomuserinfoadapter (iuserinfo)
{
This. Contract = iuserinfo;
}
# Region cumtomuserinfo Member
Public override string name
{
Get {return contract. Name ;}
Set {base. Name = value ;}
}
}
// Userinfoadapter object class Adapter
/// <Summary>
/// Set of protocol and plug-in Entity class conversion adapters
/// </Summary>
Public class userinfoadapters
{
Public static iuserinfo contracttoaddin (customuserinfo)
{
Return new customuserinfotocontractadapter (customuserinfo); // call the conversion class
}
Public static customuserinfo addmediacontract (iuserinfo)
{
Return new contracttocuntomuserinfoadapter (iuserinfo );
}
}
// Useradapter class
Public class useradapter: iusercontract
{
Private CN. codemarks. Framework. plugin. View. userview view = NULL;
Public useradapter ()
{
This. view = new useraddin ();
}
Public useradapter (userview)
{
This. view = userview; // create a plug-in
}
# Region iusercontract Member
/// <Summary>
/// Return the user object based on the user name
/// </Summary>
/// <Param name = "username"> </param>
/// <Returns> </returns>
Public CN. codemarks. Framework. plugin. Contract. entity. iuserinfo getuserinfobyname (string username)
{
Use the user name to check whether the user object customuserinfo is converted to iuserinfo
Return userinfoadapters. contracttoaddin (view. getuserinfobyname (username ));
}
Public int adduser (iuserinfo userinfo)
{
Return view. adduser (userinfoadapters. addmediacontract (userinfo ));
}
# Endregion
}
Host request plug-in data sequence diagram
More: http://www.al0574.com