From component object to codedom -- dancing your code series (1)

Source: Internet
Author: User

You can't touch a visible beauty. Being a man may be a great pain in your life;Source codeFor usProgramThis is a pretty girl.

We often have such a requirement or idea: dynamic generation or modification.Code. Of course, we can directly modify the code as a string, but this method is not too blunt and can solve the problem is limited; and the other method is codedom.

Codedom is powerful! We are grateful to Microsoft for providing us with a powerful framework for describing object-oriented languages. We are grateful to Microsoft for providing us with codedomprovider that can generate code or assembly based on codedom; we despise Microsoft and do not provide us with the ability to generate codedom from objects or code.

About codedom: This article does not cover many and interested children's shoes. You can read other articles from msdn or blog.ArticleLearn more. This series is expected to solve the problem of how to generate codedom for objects or code. Of course, because Microsoft does not provide such support, and I cannot write a codeparser that parses the C # Or VB language, the solution provided in this article is also limited, I hope I can solve some of your problems or learn some knowledge for you.

This is the first article in this series. How to Make a component object generate codedom. The core idea is to virtualize A designtime environment and add the component to the designer. Then, use componenttypecodedomserializer to serialize the component to codetypedeclaration. This scheme can be executed in any program without relying on IDE or referencing various strange DLL.

The specific implementation is as follows:

First, create a windowscontrollibrary named windowscontrollibrary1.

Then, add a class named mycomponent1. The class has a property intproperty of GetSet and a textbox with the background color set:

 

Code

    Public     Class  Mycomponent1: Component
{
Public Mycomponent1 ()
{
Textbox1 = New Textbox ();
Textbox1.backcolor = Color. Red;
}

Private Int Int1;
Private Textbox textbox1;

Public Int Intproperty
{
Get { Return Int1 ;}
Set {Int1 = Value ;}
}

Public Textbox textboxproperty
{
Get { Return Textbox1 ;}
}
}

Create another windowsformsapplication project: codedomsample and reference the system. Design and windowscontrollibrary1 projects (you can also compile windowscontrollibrary1 into a DLL and reference this DLL)

Now, create our core class codetypeconverter. I will not describe the specific implementation too much. You do not need to care about the specific implementation details, as long as this implementation can meet your needs. If you have any questions that you cannot understand, I will return to it seriously.

Code

  Public     Class  Codetypeconverter
{
Private Iserviceprovider _ serviceprovider;

Private Idesignerhost designerhost
{
Get
{
Return This . _ Serviceprovider. getservice ( Typeof (Idesignerhost )) As Idesignerhost;
}
}

// Load component to designerhost and return
Private Icomponent loadcomponent (icomponent component)
{
Designsurfacemanager Manager = New Designsurfacemanager ();
Designsurface Surface = Manager. createdesignsurface ();
Surface. beginload (component. GetType ());
This . _ Serviceprovider = Surface;
Icomponent newcomponent = Designerhost. rootcomponent;
// Brute force cloning: sets all fields on component to newcomponent.
Fieldinfo [] fields = Component. GetType (). getfields (bindingflags. nonpublic | Bindingflags. Public | Bindingflags. Static | Bindingflags. instance );
Foreach (Fieldinfo Field In Fields)
{
Object Fieldvalue = Field. getvalue (component );
// Load all child component into the designerhost
If (Fieldvalue ! = Null && Fieldvalue Is Icomponent)
{
Designerhost. Container. Add (fieldvalue As Icomponent, field. Name );
}
Field. setvalue (newcomponent, fieldvalue );
}
Return Newcomponent;
}

// Convert the component in the designerhost to codetype.
Public Codetypedeclaration convertcomponenttocodetype (icomponent component)
{
Component = This . Loadcomponent (Component) As Component;
Designerserializationmanager = New Designerserializationmanager ( This . _ Serviceprovider );
// This code is required. You must have a session and the designerserializationmanager can only work.
Idisposable session = Manager. createsession ();
Typecodedomserializer serializer = Manager. getserializer (component. GetType (), Typeof (Typecodedomserializer )) As Typecodedomserializer;
List < Object > List = New List < Object > ();
Foreach (Icomponent item In This . Designerhost. Container. components)
{
List. Add (item );
}
Codetypedeclaration Declaration = Serializer. serialize (Manager, component, list );
Session. Dispose ();
Return Declaration;
}
}

 

All right, codetypeconverter implementation is complete. Now write a test method in form1 for testing:

Code

    Public Form1 ()
{
Initializecomponent ();
Test ();
}

Public Void Test ()
{
Codetypeconverter designerhost = New Codetypeconverter ();
Mycomponent1 component = New Mycomponent1 ();
Component. intproperty = 10 ;
Component. textboxproperty. Text = " Hello World " ;

Codetypedeclaration componenttype = Designerhost. convertcomponenttocodetype (component );
Componenttype. Name = Component. GetType (). Name + " 1 " ;

Stringbuilder Bulder = New Stringbuilder ();
Stringwriter writer = New Stringwriter (Bulder, cultureinfo. invariantculture );
Codegeneratoroptions Option = New Codegeneratoroptions ();
Option. bracingstyle = " C " ;
Option. blanklinesbetweenmembers = False ;
Csharpcodeprovider codedomprovider = New Csharpcodeprovider ();
Codedomprovider. generatecodefromtype (componenttype, writer, option );
Debug. writeline (Bulder. tostring ());
Writer. Close ();
}

After codedomsample runs, the following output is displayed in the output window:

 

Code

  Public     Class  Mycomponent11: windowscontrollibrary1.mycomponent1
{
Private System. Windows. Forms. textbox textbox1;
Private Mycomponent11 ()
{
This . Initializecomponent ();
}
Private Void Initializecomponent ()
{
This . Textbox1 = New System. Windows. Forms. Textbox ();
//
// Textbox1
//
This . Textbox1.backcolor = System. Drawing. color. Red;
This . Textbox1.location = New System. Drawing. Point ( 0 , 0 );
This . Textbox1.name = " Textbox1 " ;
This . Textbox1.size = New System. Drawing. Size ( 100 , 20 );
This . Textbox1.tabindex = 0 ;
This . Textbox1.text = " Hello World " ;
//
//
//
This . Intproperty = 10 ;
}
}

 

 

 

Close the job. You are welcome to ask questions and fill the water with bricks.

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.