[Serialization] C # communication (Serial Port and network) Framework Design and Implementation-9. Plug-in engine design,

Source: Internet
Author: User

[Serialization] C # communication (Serial Port and network) Framework Design and Implementation-9. Plug-in engine design,

Contents

Chapter 9 plug-in engine design... 2

9.1 contract of the Framework-interface... 2

9.2 prototype of the plug-in-abstract class... 3

9.3 implementation interface... 4

9.4 reflection mechanism... 5

9.5 reflection tool class... 8

9.6 summary... 9

 

Chapter 9 plug-in Engine Design

Before introducing "detailed design of host programs", I will give a general introduction to interfaces and plug-ins, which will be used to design host programs, it is also the core content of interaction between the host Program and the plug-in.

9.1 contract-interface of the framework

After the Host Program of the plug-in framework is started, it first loads the corresponding configuration file (such as the device driver configuration file) and finds the corresponding plug-in assembly, these assemblies exist in the DLL file format. The host Program of the Framework finds the specified plug-in type, and the plug-in engine generates an object instance based on the plug-in type (for example, IRunDevice, the manager of the framework's host Program manages and schedules the plug-in instances.

A plug-in assembly may contain multiple plug-in types. How does the framework Host Program identify whether these types are the plug-ins to be loaded? Each plug-in object has an ID-interface, which is called a "Communication Contract" in the framework design ". An interface can be considered as a set of methods, attributes, and events that define the necessary methods. Therefore, the host program can generate a specific instance object through this contract, you can also publish operable objects to other components or interfaces.

As a platform with high aggregation and low coupling, the plug-in framework is separated between its function definition and function implementation. Any secondary development component that complies with the plug-in specifications can be mounted to the Framework Platform, and it does not focus on the specific functions of these components. Of course, the Framework Platform provides some necessary information and mechanisms to ensure that these components can normally implement the secondary development function.

In the structure design with multiple logical layers, the communication between layers is mostly implemented through interfaces, and the interfaces will not be changed easily. If the functions of one layer Change, other layers will not be affected; as long as the interface component function is implemented normally, the program runs normally. This approach minimizes the interaction between layers. In short, interfaces can be better decoupled at multiple business levels.

In most functional programming and design work, there is little need to consider the "interface" situation, if we only meet the needs of programming and using the IDE through controls. the general class libraries in the. NET Framework may never use interfaces in the program. Even in C # And Other object-oriented language grammar books, readers will see this word countless times, it only completes general functions and does not grasp the core idea of object-oriented programming.

Interfaces are definitions and contracts of common behaviors. For example, cats, dogs, and other animals, you only need to define general and public attributes and actions in the interface, such as eyes and food. Although there are many differences between different animals, the interface does not consider their own characteristics or functions, such as: what colors of eyes, what to eat and so on. It only cares about all the functions that must be implemented for these types of interfaces, and implementing this interface can be considered an animal.

Therefore, the two main functions of an interface are:

N defines public methods and attributes required for multiple types.

N is a type that cannot be instantiated.

Methods and attributes defined by the inherited interface are actually implemented as a policy.

9.2 prototype of plug-in-abstract class

Interfaces are very similar to abstract classes. For example, neither of them can create an instance object

Is used as a contract and definition. However, interfaces and abstract classes are essentially different. These differences include:

The n interface does not have any implementation part, but the abstract class can inherit the part of the implementation code after the interface.

The n interface has no fields, but the abstract class can contain fields.

The n interface can be inherited by the structure (Struct), but not the abstract class.

The n abstract class has constructor and destructor.

N interfaces can only inherit from interfaces, while abstract classes can inherit from other classes and interfaces.

N interfaces support multi-inheritance, and abstract classes only support single inheritance.

The following suggestions on interfaces and abstract classes are provided in MSDN:

N if you want to create multiple versions of a component, create an abstract class. Abstract classes provide a simple way to control component versions. By updating the base class, all inheritance classes are automatically updated with the change. On the other hand, the interface cannot be changed once it is created. to update the interface version, you must create a new interface.

N if the created function is used across a wide range of different objects, the interface is used. Abstract classes are mainly used for closely related objects, and interfaces are most suitable for providing general functions for irrelevant classes.

N interfaces should be used to design small and concise functional modules. Abstract classes should be used to design large functional units.

N if you want to provide common implemented functions among all components, you should use abstract classes. Abstract classes allow partial implementation classes, while interfaces do not include the implementation of any member.

9.3 implementation Interface

Both interfaces and abstract classes can be used as "Communication contracts" to provide standards for sub-classes. The following defines an interface and an abstract class.

// Define an interface public interface IMyInterface {void Action (int type); string Method (int para);} // define an abstract class public abstract class BaseAbstract: IMyInterface {public abstract void Action (int type); // This method must be implemented when inheriting such abstract classes. Public string Method (int para) // implement this Method {return para. ToString ();}}

The following code implements all defined methods or attributes for inherited interfaces:

public class MyClass1:IMyInterface{       public void Action(int type)       {              Console.WriteLine(type.ToString());       }             public string Method(int para)               {              return para.ToString();       }}

To inherit an abstract class, you only need to implement methods or attributes that are not implemented by the abstract class, which are generally abstract methods or attributes. The following code:

Public class MyClass2: BaseAbstract {public void Action (int type) // inherits the abstract class. You only need to implement this function. {Console. WriteLine (type. ToString ());}}
9.4 reflection mechanism

With a device driver or plug-in, it cannot be mounted to the Host Program of the Framework Platform. The question we are considering is: how does the Framework Platform generate plug-in objects in the memory based on the type definition in the Assembly with any types of plug-ins already available?

Review the process in which a program references other assembly components in normal cases. First, use the "add reference" dialog box to load the assembly. Then, use the using keyword to reference the namespace. Finally, find the corresponding class in the Command space and create an instance. This is a way to load the Assembly statically.

This method is not suitable for plug-in application frameworks. The Host Program does not know which Assembly it will process during compilation, nor can it statically introduce the plug-in type through the using Keyword. These are all information that can be obtained at runtime. In this case, the static method and the new Keyword cannot be used to generate an instance of the type. Instead, you need to obtain relevant information at runtime to dynamically load the Assembly. This process is called reflection.

Reflection is a kind of capability for dynamically discovering type information. It is similar to later binding. It helps developers use the assembly information to dynamically use types during program running. This information is unknown during compilation, reflection also supports more advanced behaviors, such as dynamically creating new types at runtime and calling methods of these types.

The JIT compiler will check the types referenced in the IL code when compiling the code at a cost. At runtime, the JIT compiler uses the TypeRef of the Assembly and the record items of the AssemblyRef meta data table to determine which Assembly defines the referenced type. In the AssemblyRef metadata record item, each part of the strong name of the Assembly is recorded, including the name, version, Public Key tag, and language culture. These four parts constitute a string identifier. The JIT compiler tries to load the Assembly that matches this identifier into the current AppDomain. If the Assembly is weakly named, the identifier will only contain the name.

In. NET Framework, you must be familiar with methods of tool classes such as Assembly, Type, and Activator for dynamic loading. The Framework Platform mainly uses the Assembly Tool class, which includes Load, LoadFrom, and LoadFile.

1.AssemblyLoadMethod

In the internal CLR, the Load method of Assembly is used to Load the Assembly. This method is equivalent to the LoadLibray method of Win32. Internally, Load causes CLR to apply a version redirection policy to the Assembly. Find the Assembly in GAC. If the Assembly is not found, search for the application's base Directory, private path directory, and location specified by codebase. If it is a weak named assembly, Load will not apply the Redirection policy to the Assembly, nor will it go to GAC to find the assembly. If it is found, an Assembly reference is returned. If it is not found, a FileNotFoundException exception is thrown. Note: If the Load method has loaded an assembly with the same identity, it will simply return the reference of this Assembly, rather than creating a new assembly.

In most dynamically scalable applications, the Assembly Load method is the preferred method for loading an Assembly to the AppDomain. In this way, you must specify the identity string of the Assembly. Only one name is specified for the weak naming assembly.

2. AssemblyLoadFromMethod

When we know the Path of the Assembly, we can use the LoadFrom method, which allows passing in a Path string. Internally, LoadFrom first calls the static method GetAssemblyName of AssemblyName. This method opens the specified file, extracts the Assembly ID from the AssemblyRef metadata table, and closes the file. Subsequently, LoadFrom internally calls the Load method of Assembly to find the Assembly. Here, his behavior is consistent with the Load method. The only difference is that if the assembly is not found by Load, LoadFrom loads the Assembly specified by Path. In addition, the Path can be a URL.

3. AssemblyLoadFileMethod

This method is similar to the LoadFrom method. However, the LoadFile method does not internally call the Load method of Assembly. It only loads the Assembly with the specified Path, and this method can load the Assembly from any Path. If the same assembly is in a different Path, it can be loaded multiple times, an assembly with the same name is loaded into the AppDomain, which is totally different from the preceding two methods. However, LoadFile does not load the dependencies of the Assembly, that is, it does not load other Assembly referenced by the Assembly, which leads to exceptions that cannot be found in other reference DLL during runtime. To solve this problem, you must register with the AssemblyResolve event of AppDomain and display the referenced assembly in the callback method. Similar to this:

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args){       if (args.Name != null)       {              return Assembly.LoadFrom(string.Format("{0}\\plugin\\{1}.dll", Application.StartupPath, new AssemblyName(args.Name).Name));       }       return null;}

Note: To test whether LoadFile has loaded the referenced DLL, do not copy the DLL to the root directory of the application. This directory is the default directory for CLR to load the assembly, if a referenced DLL exists in this directory, it will be loaded, resulting in the illusion that LoadFile will load the referenced DLL. You can create a new sub-directory such as plugin under the root directory and copy the referenced dll to this directory for testing.

Reflection mechanisms also have their drawbacks: security and performance. However, reflection is required when the Framework Platform is started and when new device drivers (plug-ins) are added. Once loaded into the host program, there is no essential difference from static reference assembly, all are stored in the memory.

9.5 reflection Tool

The plug-in Framework Platform uses reflection to mount the device driver and runs in the Host Program. A dedicated tool class is required to complete related functions. The code is defined as follows:

/// <Summary> /// a lightweight IObjectBuilder implementation /// </summary> public class TypeCreator: IObjectBuilder {public T BuildUp <T> () where T: new () {return Activator. createInstance <T> ();} public T BuildUp <T> (string typeName) {return (T) Activator. createInstance (Type. getType (typeName);} public T BuildUp <T> (object [] args) {object result = Activator. createInstance (typeof (T), args); return (T) result;} // <sum Mary> // The Framework Platform mainly uses this function. /// </Summary> /// <typeparam name = "T"> </typeparam> /// <param name = "assemblyname"> </param> /// <param name = "instancename"> </param> // <returns> </returns> public T BuildUp <T> (string assemblyname, string instancename) {if (! System. IO. file. exists (assemblyname) {throw new FileNotFoundException (assemblyname + "");} System. reflection. assembly assmble = System. reflection. assembly. loadFrom (assemblyname); object tmpobj = assmble. createInstance (instancename); return (T) tmpobj;} public T BuildUp <T> (string typeName, object [] args) {object result = Activator. createInstance (Type. getType (typeName), args); return (T) result ;}}
Conclusion 9.6

The next section describes the detailed design of the Host Program. You must have a certain understanding of the reflection mechanism and use the tool class above for extension.

The Framework Platform has to be complete. It only takes a small step.

 

Author: Wei Xiaozhi

Email: 504547114@qq.com

QQ: 504547114

. NET Development Technology Alliance: 54256083

Document Download: http://pan.baidu.com/s/1pJ7lZWf

Http://www.bmpj.net

Related Article

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.