UML软件工程组织

使用 CodeDOM 命名空间将模板的威力带到您的 .NET 应用程序中

 

作者:Adam J. Steinert  文章来源:microsoft

 

Figure 1 Hello World Template Reference

namespace HelloWorld {
using System;
using System.Drawing;
using System.Windows.Forms;

public class HelloWorldForm : System.Windows.Forms.Form {

private System.Windows.Forms.TextBox txtSourceCode;

public HelloWorldForm() {
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.Text = "Hello, World!";
this.Size = new System.Drawing.Size(700, 350);
txtSourceCode = new System.Windows.Forms.TextBox();
this.Controls.Add(txtSourceCode);
txtSourceCode.Multiline = true;
txtSourceCode.ScrollBars = ScrollBars.Both;
txtSourceCode.Top = 10;
txtSourceCode.Width = 10;
txtSourceCode.Size = new System.Drawing.Size(690, 300);
txtSourceCode.Anchor = (AnchorStyles.Bottom
| (AnchorStyles.Top
| (AnchorStyles.Left | AnchorStyles.Right)));
txtSourceCode.Text = "[Little Recursive Box]";
}
}

public class HelloApplication {

public static void Main() {
HelloWorldForm hwApp;
hwApp = new HelloWorldForm();
hwApp.ShowDialog();
}
}
}

Figure 2 Creating the HelloWorldForm Class

private CodeTypeDeclaration BuildFormClass() {
CodeTypeDeclaration FormClass = new CodeTypeDeclaration();
CodeEntryPointMethod MainMethod = new CodeEntryPointMethod();

// Set up Class
FormClass.Name = "HelloWorldForm";
FormClass.IsClass = true;
FormClass.BaseTypes.Add(new CodeTypeReference(
typeof(System.Windows.Forms.Form)));

FormClass.Attributes = MemberAttributes.Public;

// set up members
FormClass.Members.Add(new CodeMemberField(
typeof(System.Windows.Forms.TextBox), "txtSourceCode"));

// set up constructor
FormClass.Members.Add(BuildFormConstructor());

return FormClass;
}

Figure 3 Creating the HelloApplication Class

private CodeTypeDeclaration BuildAppClass() {
String TypeString = "HelloWorldForm";

if(UseFullNamespace) {
TypeString = "HelloWorld." + TypeString;
}

CodeTypeDeclaration hwAppClass =
new CodeTypeDeclaration("HelloApplication");
CodeEntryPointMethod MainMethod = new CodeEntryPointMethod();

hwAppClass.IsClass = true;
hwAppClass.Attributes = MemberAttributes.Public;

MainMethod.Attributes = MemberAttributes.Public |
MemberAttributes.Static;
MainMethod.ReturnType = new CodeTypeReference(typeof(void));
CodeExpression[] prmRun = { new CodeObjectCreateExpression(
"HelloWorld", new CodeExpression[0]) };

MainMethod.Statements.Add(new CodeVariableDeclarationStatement(
new CodeTypeReference(TypeString), "hwApp"));

CodeExpression[] hwParams = new CodeExpression[0];
MainMethod.Statements.Add(new CodeAssignStatement(
new CodeVariableReferenceExpression("hwApp"),
new CodeObjectCreateExpression(TypeString, hwParams)));


MainMethod.Statements.Add( new CodeMethodInvokeExpression(
new CodeVariableReferenceExpression("hwApp"),
"ShowDialog", hwParams));

hwAppClass.Members.Add(MainMethod);

return hwAppClass;
}

Figure 4 BuildFormConstructor Excerpt

private CodeConstructor BuildFormConstructor() {
CodeConstructor hwConstructor = new CodeConstructor();
CodeThisReferenceExpression oThis =
new CodeThisReferenceExpression();
CodeStatementCollection stCol = new CodeStatementCollection();

hwConstructor.Attributes = MemberAttributes.Public;

 

prmSizeArgs[0] = new CodePrimitiveExpression(700);
prmSizeArgs[1] = new CodePrimitiveExpression(350);
stCol.Add(new CodeAssignStatement(
new CodePropertyReferenceExpression(oThis, "Size"),
new CodeObjectCreateExpression(typeof(System.Drawing.Size),
prmSizeArgs)));

 

CodeTypeReferenceExpression oAnchor =
new CodeTypeReferenceExpression("AnchorStyles");
CodeBinaryOperatorExpression AnchorStyles =
new CodeBinaryOperatorExpression(
new CodeFieldReferenceExpression(oAnchor, "Bottom"),
CodeBinaryOperatorType.BitwiseOr,
new CodeBinaryOperatorExpression(
new CodeFieldReferenceExpression(oAnchor, "Top"),
CodeBinaryOperatorType.BitwiseOr,
new CodeBinaryOperatorExpression(
new CodeFieldReferenceExpression(oAnchor, "Left"),
CodeBinaryOperatorType.BitwiseOr,
new CodeFieldReferenceExpression(oAnchor, "Right"))));

 

hwConstructor.Statements.AddRange(stCol);
return hwConstructor;
}

Figure 5 Main Form Generator
 

 Figure 6 Generating Preview Code

// Create our source Graph for each language
foreach(LanguageItem Lang in cboTargetLanguage.Items) {
if(Lang.LanguageID == Language.JScript) {
HelloWorldApp.UseFullNamespace = true;
} else {
HelloWorldApp.UseFullNamespace = false;
}
hwCompileUnit = HelloWorldApp.GenerateCCU();
hwGenerator = GetLanguageGenerator(Lang.LanguageID);

CodeText = new StringWriter();
hwGenerator.GenerateCodeFromCompileUnit(hwCompileUnit,
CodeText,
GeneratorOptions);
((TextBox)PreviewText[PT_PREFIX + Lang.LanguagePreviewID]).Text
= CodeText.ToString();

CodeText.Close();
}

Figure 7 GeneratorSupport Enumeration Values

ArraysOfArrays MultiDimensionalArrays
AssemblyAttributes MultipleInterfaceMembers
ChainedConstructorArguments NestedTypes
ComplexExpressions ParameterAttributes
DeclareDelegates PublicStaticMembers
DeclareEnums ReferenceParameters
DeclareEvents ReturnTypeAttributes
DeclareInterfaces StaticConstructors
DeclareValueTypes TryCatchStatements
EntryPointMethod Win32Resources

Figure 8 Eiffel Source for HelloWorldForm

class
HELLO_WORLD_FORM

inherit
FORM

create
a_ctor

feature -- Initialization

a_ctor is
do
set_auto_scale_base_size (
create {SIZE}.make_from_width_and_height (5, 13))
set_text (("Hello, World!").to_cil)
set_size (create {SIZE}.make_from_width_and_height (700, 350))
create source.make
get_controls.add (source)
txtSourceCode.set_multiline (True)
txtSourceCode.set_scroll_bars (both)
txtSourceCode.set_top (10)
txtSourceCode.set_width (10)
txtSourceCode.set_size (
create {SIZE}.make_from_width_and_height (690, 300))
txtSourceCode.set_anchor (bottom or top or left or right)
txtSourceCode.set_text (("[Little Recursive Box]").to_cil)
end

feature -- Access

txtSourceCode: TEXT_BOX

end -- HELLOWORLDFORM

Figure 9 CreateExtendedCompileUnit

private void CreateExtendedCompileUnit(ICodeGenerator hwGenerator,
ref CodeCompileUnit hwCompileUnit,
CodeGeneratorOptions GeneratorOptions,
TemplateConstructor HelloWorldApp) {

StringWriter CodeText = new StringWriter();

// Generate code with text placeholder
hwGenerator.GenerateCodeFromCompileUnit(hwCompileUnit, CodeText,
GeneratorOptions);
HelloWorldApp.SourceText = new
CodePrimitiveExpression(CodeText.ToString());
hwCompileUnit = HelloWorldApp.GenerateCCU();
}

Figure 11 Populating the Generator Class ComboBox

foreach(Type curType in types) {
GeneratorMethods CurGenMethods = new GeneratorMethods();
if(curType.IsClass) {
CurGenMethods.CCUGeneratorMethod = curType.GetMethod("GenerateCCU");
CurGenMethods.QueryVarsMethod = curType.GetMethod("QueryVariables");
CurGenMethods.SetVarsMethod = curType.GetMethod("SetVariables");
CurGenMethods.GetNameMethod = curType.GetMethod("GetName");

if(CurGenMethods.IsValid()) {
CurGenMethods.ClassName = curType.FullName;
if(CurGenMethods.GetNameMethod != null) {
CurGenMethods.FriendlyName = GetProviderName(CurGenMethods);
}
cboClasses.Items.Add(CurGenMethods);
bClassFound = true;
}
}
}

Figure 12 Replacing Type Information in Templates

CodeMemberProperty DefaultProperty = new CodeMemberProperty();
CodeExpression[] HashIndex =
new CodeExpression[1] { new CodeArgumentReferenceExpression("Key") };

CodeIndexerExpression InternalDefaultReference =
new CodeIndexerExpression(InternalHash, HashIndex);

DefaultProperty.Name = "Item";
DefaultProperty.Attributes = MemberAttributes.Public;
DefaultProperty.Parameters.Add(new
CodeParameterDeclarationExpression(
TemplateVariables[T_KEYTYPE], "Key"));
DefaultProperty.Type =
new CodeTypeReference(TemplateVariables[T_VALUETYPE]);

// Get Statement
DefaultProperty.GetStatements.Add(new CodeMethodReturnStatement(
new CodeCastExpression(TemplateVariables[T_VALUETYPE],
InternalDefaultReference)));

// Set Statement
DefaultProperty.SetStatements.Add(
new CodeAssignStatement(InternalDefaultReference,
new CodePropertySetValueReferenceExpression()));

TypedHash.Members.Add(DefaultProperty);

 


版权所有:UML软件工程组织