The. NET programmers who have worked for five years talk about application reflection, dynamic compilation, and code generator.

Source: Internet
Author: User
Tags reflector

I have been working for many years. the representatives of the net practical school, without too many empty theories, only talk about practical skills, and combine technologies, knowledge, and tools to make more changes to their own lives and improve productivity. The previous topic, I learned after years of work. net underlying development technology. All of them think that the reflection examples are too superficial and not enjoyable. The reflection examples of this subject may not disappoint you.
This topic comes from the template editor process with smart prompts. See the following example.Program. The purpose is to intelligently display its member list when you input the math variable in the template, that is, to create a template editor with smart prompts.

The template syntax is defined as follows:
<% @ Property name = "math" type = "mathprogram" Category = "text" Description = "namespace for this class" %>
<% @ Property name = "includedelete" type = "system. int32" default = "123" Category = "options" Description = "if true Delete statements will be generated." %>

<% @ Assembly name = "testclasslibrary" %>
<% @ Import namespace = "EPN. Common" %>

If you are not familiar with this syntax, you can refer to the Getting Started tutorial of code Smith orArticleOrm framework-tools-Product Development 4 Development Code Generator template Studio development.

Use a concise language to explain this sectionCodeDefines a variable math of the mathprogram type, which is defined in the EPN. Common namespace of the testclasslibrary assembly. The Code definition of the mathprogram type is as follows:

[Typeconverter (typeof (expandconverter)]
Public class mathprogram
{
Public mathprogram (string system, string Application)
{
_ Systemname = system;
_ Applictionname = application;
}

Public mathprogram (){}

Public int add (int A, int B)
{
Return A + B;
}

Public int substract (int A, int B)
{
Return A-B;
}

Public static string Product = "template Studio ";

Private string _ systemname;
[Browsable (true)] [category ("text")] [defaultvalue ("")] [description ("namespace for this class")]
Public String systemname
{
Get {return _ systemname ;}
Set {_ systemname = value ;}
}

Private string _ applictionname;

[Browsable (true)] [category ("text")] [defaultvalue ("")] [description ("namespace for this class")]
Public String applictionname
{
Get {return _ applictionname ;}
Set {_ applictionname = value ;}
}

}

The result I want to achieve is that when the math variable is typed in the template, its member list can be intelligently displayed.

To demonstrate the feasibility of this technology, let's take a look at the results achieved in code Smith.

This technology is one of the selling points of code Smith, a useful template editor with smart prompts.

At this point, you may be curious about this technology, how it is implemented, and how I implement this function. The following describes its principles and implementation code.

 

. Net Editor, very concerned about the dot. c ++ has three symbols at the same time.,->,: Can all represent Member calls. When you press the dot symbol, the editor starts the analysis program, analyzes the token before the dot, and finds its type. If it is a type definition, its members will be listed. This is a common but important feature of Visual Studio. This function has been implemented by many editors and can be called directly.

However, the template editor has some special features, because we usually write code like this.

Mathprogram math = new mathprogram ();

Math. systemname; The systemname variable can be displayed according to smart prompts.

In the template editor, the Code definition is as follows:

<% @ Property name = "math" type = "mathprogram" Category = "text" Description = "namespace for this class" %>
This statement is also equivalent to the code snippet mathprogram math = new mathprogram ();

After you have knocked out the property %>, the analyzer should add the code snippet mathprogram math = new mathprogram () in the background ();

. NET 2.0 and later support the partial keyword, allowing the type definition to be placed in multipleSource codeIn the file, the code is automatically merged during compilation. I parse the template content into a C # code file, and the type name is taken from the Template Name. In this way, every time the template changes, the background process will re-analyze the template content and regenerate the C # code file for member definition. It seems that the smart question should be solved here.

However, no, it cannot achieve the goal. in C #, global variables are not allowed, that is, they are defined in one place and called in another place. I can define a variable in the C # code in the background, but this variable cannot be obtained in the template file.. NET is the language of OOP and global variables are not allowed.

In another case, when we enter a type name and click a number, it immediately displays its static members. This feature helps me solve the problem.

Let's review the template's property definition syntax. The type is mathprogram and the variable name is math.

<% @ Property name = "math" type = "mathprogram" Category = "text" Description = "namespace for this class" %>

After entering this syntax, I construct a math type in the background instead of a variable (because C # does not allow global variables). When you type the math attribute in the template file, it will take the type defined in the background. As for the display of its members, it is very easy to append the members in mathprogram to my background definition type math, in addition, the static attribute is added. In this way, the point after the template attribute math is called is equivalent to the math type generated in my background. The method is taken from the instance method and attribute of mathprogram.

 

The problem is that reflection must be applied. I need to construct its source code based on the Type EPN. Common. mathprogram in the Assembly testclasslibrary for smart prompts in my editor. Construct its source code based on the Assembly. The code looks like this

String namespace = "EPN. Common ";
String typename = "mathprogram ";
String fullname = namespace + "." + typename;
String InstanceName = "math ";

String assemblyname = "testclasslibrary ";
String source = codedomhelper. buildspecifiedtypesourcecode (assemblyname, fullname, InstanceName );

Here, you may understand the meaning of the property in the template syntax of code Smith. I have no chance to read the source code of code Smith, but these lines of code are enough to help you deeply understand its meaning and understand why.

 

Let's take a look at how to generate its source code based on the Assembly. I am not referring to the use of tools such as reflector to generate source code. In my template studio, there is no chance to do this at all. Users cannot help you decompile the Assembly and provide the source code, then you can display its member list.
The first intuitive impression is that command line calls the reflector program to help decompile the program into source code.
CMD-> reflector "testlibrary" "EPN. Common. mathprogram" "C: \ DNA \ math. CS"
It is expressed in language. I want to pass in the Assembly and need to decompile the type, and then retrieve its source code from the specified file.
Unfortunately, for the moment, reflector cannot do this. The official website has regarded this as a feature, but it is unknown when it will be implemented.

Another good anti-compiler, ilspy, is open source code. However, we didn't see any example of command line calling and failed.
The third idea is to write reflector's plug-in, which already has reflector. filedisassembler. DLL. With this component, you can export an assembly as one at a time. net source code, reflector7 built-in this component, see the figure


So I want to view the source code of reflector's export assembly Source Code menu command. But you know, it is not feasible to use reflector to read its own source code. Selling tools to you allows you to deal with others' Assembly, rather than using them on your own.

At this point, you will find that there are not many materials on the Internet. These materials will never be made public. It seems that you have to rely on yourself or make changes, or discard the implementation of this feature.

Let's continue to look at the problem. What my smart editor needs is EPN. common. the source code of the mathprogram type does not need its complete source code. You only need to obtain the code signature. Specifically, the attribute definition and method only need to be signed to achieve the goal. Because I only use it as the content of the smart prompt, and do not need to execute it, the Code content is not required, and the body can be ignored. Therefore, I need the following code:

Public class math
{
Public static int add (int A, int B)
{
Return 2012;
}

Public static int substract (int A, int B)
{
Return 2012;
}

Public static string systemname
{
Get {return "2012 ";}
Set {}
}

Public static string applictionname
{
Get {"2012 ";}
Set {}
}

}

As you can see in the code, I generate a property of the static type, and the method body is empty. When you type math in the Visual Studio code editor, it intelligently lists the above members, because they are all static. After comparing the template definition, we regard the attribute name math in the template as the math type here, that isAfter the math variable is input in code Smith, the result is intelligently indicated..

Now let's analyze the code generation technology. I think you must be interested in this Code.

String source = codedomhelper. buildspecifiedtypesourcecode (assemblyname, fullname, InstanceName );

Yes, this is the code generation technology, which generates its source code according to the Assembly. Depending on the name codedom, you may have guessed its implementation.

I did implement it using codedom technology, because codedom is the best technical choice to support both VB and C # code. In this way, my template can support both C # and VB syntaxes. The background codedom helps me generate source code files for both VB and C # syntaxes, for smart prompts. In fact, I didn't consider using codedom as a code generation tool at first, because its syntax is a little ugly and hard to understand. At first, I used C # to piece together strings, generate the C # source code file, and then call the following tool to directly convert it into the VB syntax.

Code conversion is a previously written tool for converting C # and VB code. Because there is source code, it is no difference to convert C # to VB using code conversion. After a hard time starting the software, I clicked a few menus and used code to call the software. I immediately converted all the C # code into the VB code, which is the magic of the Code.

After reviewing this process, C # code is compiled into an assembly and added to the template application. The template editor background program analyzes the assembly type definition and generates its source code skeleton, it is used to display the member list of the smart prompt form. To support the VB and C # syntax, select the codedom technology to generate code.

 

Summary: I admit that I have hidden many implementation details. Since I have already achieved this effect, I can confidently say that it has applied a lot of reflection, dynamic compilation and codedom code generation technology. The idea of writing an article is broken down. We should focus on the Implementation points, but we should be able to combine them into a whole, starting from contract, connecting up and down, so that we can have a thorough understanding. I understand that you urgently need the C # files to connect the code and ideas of this article into a whole. After the articles in the "ORM framework-tools-Product Development" series are published one after another, you may have the opportunity to see the implementation of these codes.

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.