ORM framework-tools-Product Development 4 Development Code Generator template studio Development (2)

Source: Internet
Author: User

ORM tool development seriesCodeGenerate the development of the tool, connect it back, and continue to design the template-based code generator.

Template editor

The basic requirements of the editor are file editing (copy, cut, paste, find/replace), syntax highlighting, and smart prompts.

Built-in types of. NET systems can be pre-loaded and provide smart notification functions.

You can directly reference the built-in system type. When editing a template, the smart Prompt window is automatically displayed.

If you can customize variables to achieve this effect, it brings a great deal to the template writing, as shown in the prompt window for Custom Attributes math.

One difficulty in parsing a custom type is that it is dynamically added and cannot be known in advance. For example

Enter the attribute includedelete first, which is a simple type and does not require support by smart prompts.
<% @ Property name = "includedelete" type = "system. int32" default = "123" Category = "options" Description = "if true Delete statements will be generated." %>

Write another custom mathprogram named math.

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

The parser still cannot work because it does not know where the mathprogram type comes from and what level of namespace it belongs. (. NET allows the sameProgramSet, with the same type name under different namespaces ). When the following statements are completed

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

The parser will go to the namespace EPN. Common of the Assembly testclasslibrary to find the mathprogram type. If the type definition can be found, it will be added to the smart Prompt window; otherwise, it will not be added.

The Code is as follows:

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

<% @ Assembly name = "testproviderlibrary" %>
<% @ Import namespace = "paradox. Common" %>

There is a type declaration, the Code is as follows:

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

In this way, you need to match the two namespaces of the preceding two sets. If you find the specified type definition, you can add the smart notification member. Worse, the EPN. Common namespace of the Assembly testclasslibrary and paradox. Common namespace of the Assembly testproviderlibrary both contain the definition of the mathprogram type. In this case, the compilation error should be reported.

 

Prototype generated by template code

Based on the following steps, the generated code is pushed back to the template definition to explain the basic model generated by the template code.

Suppose the target code is like this, a simple type definition

Public class mathprogram

{

Public mathprogram ()

{

}

}

Replace with a simple variable. You can write this code, that is, replace the type name with a string value.

<% Private string classname = "mathprogram"; %>

Public class <% = classname %>

{

Public <% = classname %> ()

{

}

}

How can variables be replaced? Put the above code into a stream and replace the variable definition during execution.

String classname = "mathprogram ";

Memorystream mstream = new memorystream ();

Streamwriter writer = new

Streamwriter (mstream, system. Text. encoding. utf8 );

Writer. Write (@ "public class );

Writer. Write (classname );

Writer. Write (@"{

Public );

Writer. Write (classname );

Writer. Write (@"()

{

}

});

Streamreader sr = new streamreader (mstream );

Writer. Flush ();

Mstream. Position = 0;

String code = Sr. readtoend ();

The final variable code is the result we need.

Further, the string value can be input by the user or set through the properties form, which is like this

<% @ Property name = "classname" type = "string" Category = "name" default = "mathprogram" %>

Public class <% = classname %>

{

Public <% = classname %> ()

{

}

}

In this way, you can use the properties form to change the type name, instead of changing the default value "mathprogram" in the template every time ".

What does replacement mean during execution? Understanding the meaning of this sentence: the template will be converted into a type definition by the parsing engine, and then dynamically compiled into a type, and the result of the input type of the method that calls it. In the previousArticleI understand it after years of work. the wage formula compiler mentioned in net underlying development technology is also the principle of constructing a type, executing it, and finally obtaining the execution result, is the generated code we need.

The code looks like this: generate an assembly, call a method of the specified type, and obtain the execution result of the method.

Assembly = createassembly (sourcetemplate, parameters)
Type type = assembly. GetType ("Builder ");

Invokemethod (type, "render", new object [] {"mathprogram "});
The custom assembly can be put in the specified directory in the following way.

<Runtime>
<Assemblybinding xmlns = "urn: Schemas-Microsoft-com: ASM. V1">
<Probing privatepath = "bin; addins; Providers"/>
</Assemblybinding>
</Runtime>

This setting allows bin, addins, and providers directories to store assembly files without filenotfoundedexception during load.

 

Templates in multiple syntax formats

Currently, the Orthodox languages of. NET are VB. Ne and C #. The popular J # and Delphi. Net have all withdrawn from the market. Template studio must also support templates in these two languages. The syntax is still compatible with the code Smith syntax declaration.

<% @ Codetemplate Language = "C #" targetlanguage = "C #" Description = "generates a very simple business object." %>

VB. NET is written as follows:

<% @ Codetemplate Language = "VB" targetlanguage = "C #" Description = "generates a very simple business object." %>

If the language is VB, variables must be defined in the Code or where the code segment is included, the VB syntax should be used.
Attribute Definition
<% Private const run_multiplier as integer = 10%>
Code snippet

<% For I = 0 to run_multiplier-1%>
<% = Math. applictionname %> <% = I %>
<% Next I %>

In addition, when designing the generated types, you should also note that you should use the VB syntax instead of the C # syntax code.

During compilation, you must change the compiler from csharpcodeprovider to vbcodeprovider to compileSource codeType.

 

Flexible and plug-in-based using provider pattern use the provider mode to implement flexible plug-in programming

At the beginning of ASP. NET release, the provider mode was first proposed through the famous Forum program community sever and ASP. NET forum.

First, copy a paragraph statement to praise the provider mode.

The Provider Model of Asp.net 2.0 provides developers with an extensible method to add their own implementations as a feature to the runtime. Both membership provider and role provider follow the Provider Model by refining an interface or protocol in Asp.net 2.0. If you create your component to implement the protocol defined by the provider model, you can insert your code to the Asp.net runtime and replace or extend the existing provider. The Provider Model in Asp.net 2.0 includes a provider configuration and initialization infrastructure.

The following code provides an example to help you understand the provider mode.

Public abstract class providerbase
{
Protected string name;
Protected string description;
Public string name {Get ;}
Public String description {Get ;}
Public abstract void initialize ();

Public abstract void GENERATESCHEMA ();
}
Public abstract class sqlserverprovider: providerbase
{

Public override void GENERATESCHEMA (){}
}
Public class mysqlprovider: providerbase
{
Public override void GENERATESCHEMA (){}

}

Public static class schemaprovider
{
Static schemaprovider ()
{
}
Static providerbase provider;
Public static providerbase provider {get {return provider ;}}
Public static providerbase instance
{

If (provider = NULL)

{

Swith (databasetype)

{

Case databasetype. sqlserver:

Provider = new sqlserverprovider ();

Break;

Case databasetype. MySQL:

Provider = new mysqlprovider ();

Break;

}

}
Return provider
}
}

The configuration file will be used in the formal provider example. I have simplified it here and can directly use the code for judgment.

Application Example of the provider mode in template Studio
1) connect to the database server and obtain metadata

2) generate template code. Two code generators, VB and C #, implement different codes of the same type (VB. NET and C #)

 

Advanced topic of Code Generator

1) Batch code generation is supported. For example, if a data table gbitem corresponds to an itementity object, four types must be generated for it: itementity. CS, itemvalidation. CS, iteminterface. CS, itemmanager. CS

To be supported, generate these four types at the same time in one step, usually four code files in utf8 format.

Like llbl Gen 3. X, bind multiple templates to a templatebinding file and input a llblgenproj project file.

2) The code generated by the template must be called by a third-party tool. In Smith builder, my open-source tool, the most valuable code is to get the parameter value, upload it to the template, and generate code in batches.

As shown in the following code, it can be called in code mode, which is not limited by IDE template studio and can be flexibly used.

Use the sample code in the Code Smith SDK as follows:

dim compiler as codetemplatecompiler
compiler = new codetemplatecompiler ("storedprocedures. CST ")
compiler. compile ()
If compiler. errors. count = 0 then
dim template as codetemplate
template = compiler. createinstance ()

dim database as databaseschema
database = new databaseschema (New sqlschemaprovider (), "Data Source =. \ sqlexpress; attachdbfilename = petshop. MDF; Integrated Security = true; Connect timeout = 30; user instance = true ")
dim table as tableschema
table = database. tables ("inventory")

template. setproperty ("sourcetable", table)
template. setproperty ("includedrop", false)
template. setproperty ("insertprefix", "insert")

Template. Render (console. out)
Else
Dim I as integer
For I = 0 to compiler. errors. Count
Console. Error. writeline (compiler. errors (I). tostring ())
Console. Read ()
Next
End if

The power of this capability is enormous, which means that templates can be integrated by third-party tools without the existence of IDE. Code Smith itself is free of charge, it only charges code Smith studio, integrated editing, debugging template IDE.

Only for this reason can it be called by the ORM tool as an API, as shown in

Orm. Net is a popular ORM tool in the. NET 1. x era. Unfortunately, it was stopped later. It seems that the open-source idea can be fulfilled. If it is not open-source or commercialized, it may be much better to develop. As soon as many projects are put on the Internet, updates are slowly stopped.

 

3) supports mainstream databases. Common databases such as SQL Server, Oracle, and MySQL all need to write an assembly to obtain metadata for code generation. This is not difficult. There is an open-source code Smith prover as an example. You can also refer to the dynamic query Enginee, DQE, and dynamic query engine mentioned in llbl Gen 3.x source code tracing and parsing query command tracing to reference different assembly for different databases.

In Template studio, This is not difficult, but it is put into the ORM framework-tools-Product Development (big picture). This part is an important feature of the ORM framework: supports multiple database platforms. Orm is inherently independent of databases and does not rely on database features.

This section focuses on the ORM framework-tools-Product Development ORM framework.

 

4) Multi-orientation in. Net assembly

Recall a scenario. After the release of vs2005, Microsoft has successively released technologies for. Net 3.0/3.5, such as WCF and WPF. If the target of the source code to be compiled is. NET 2.0, the version of the assembly to be referenced can be. Net 3.0/3.5. At that time, vs2005 can be used to do this. But later vs2008 was released. This benefit disappears, and even vs2010 cannot be used to reference the assembly of the higher version target with the assembly of the lower version target.

What will this affect? Assume that the target of testclasslibrary compilation is. Net 4.0, and the target of template studio is. Net 20, which is referenced as follows:

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

This will affect the execution result. This problem can be solved by setting the application to run on version 3.5.

<Runtime>
<Compatibilityversion major = "3" minor = "0"/>
</Runtime> <startup> <supportedruntime version = "v3.5.7000"/>
</Startup>

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.