DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft...

55
DEV485 .NET CodeDOM demystified Beat Schwegler Architect Evangelist .NET Developer Group Microsoft Corporation

Transcript of DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft...

Page 1: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

DEV485

.NET CodeDOM demystified

Beat Schwegler

Architect Evangelist

.NET Developer Group

Microsoft Corporation

Page 2: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Agenda

CodeDOMIntroduction

Assembly compilation

Source code generation

Source code parsing

Advanced conceptsTemplate based source code generation

On-the-fly proxy generation

Page 3: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

CodeDOM scenarios

.NET Framework scenariosASP.NET assembly generation

WSDL proxy generation

Managed C++ WinForms designer

VS code wizards

Custom scenariosGeneration of typesafe collections

Source code skeleton generation

On the fly tie-pattern generation

Page 4: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

CodeDOM namespaces

System.CodeDom Contains the Code Document Object Model (CodeDOM) graph types

System.CodeDom.CompilerContract for all CodeDomProviders

Contains interfaces and (abstract) base classes

Page 5: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

CodeDOM providers

Microsoft providersC#, VB.NET, Managed C++, Jscript, J#

Microsoft partnersNetCOBOL (Fujitsu)

ActivePERL (ActiveState)

Eiffel (Interactive Software Engineering)

Page 6: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

HelloWorld CodeDom graph

namespace Samples{ using System; public class Hello { public void SayHello() { Console.WriteLine("Hello World!"); } }}

CompileUnitCompileUnit

NamespacesNamespaces

Namespace Sample Namespace Sample

ImportsImports TypesTypes

Class HelloWorldClass HelloWorld

MembersMembers

Method SayHelloMethod SayHello

StatementsStatements

ExpressionExpression

SystemSystem

Page 7: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

CodeDOM graphIndependent of programming language

In-memory representation of a source code document

Tree based object model

Doesn’t support all language specific features (no unsafe, no variable declaration lists, …)

Compiles if the root element is of type CodeCompileUnit

Page 8: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

CodeDOM concepts

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

Source codeSource code

CompileUnitCompileUnit

NamespacesNamespaces

Namespace Sample Namespace Sample

ImportsImports TypesTypes

Class HelloWorldClass HelloWorld

MembersMembers

Method SayHelloMethod SayHello

StatementsStatements

ExpressionExpression

SystemSystem

CodeDOM graphCodeDOM graph

AssemblyAssembly

compilingcompilingCodeDOM graphCodeDOM graph

compilingcompilingsource codesource code

parsingparsingsource codesource code

generatinggeneratingsource codesource code

Page 9: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Programming model

Creating the code providerCodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider();

Obtaining the required interfaceICodeGenerator generator = provider.CreateGenerator();

Calling the method

generator.GenerateCodeFromCompileUnit(…);

Page 10: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

CodeDOM

Compiling an assembly on the flyIn-memory

stored to disk

Generating code according to an in-memory CodeDOM graph

Several code providers are already available (C#, VB.NET, J#, Managed C++)

Parsing code to get an in-memory CodeDOM graph

Page 11: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Agenda

CodeDOMIntroduction

Assembly compilation

Source code generation

Source code parsing

Advanced conceptsTemplate based source code generation

On-the-fly proxy generation

Page 12: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Assembly compilation

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

Source codeSource code

CompileUnitCompileUnit

NamespacesNamespaces

Namespace Sample Namespace Sample

ImportsImports TypesTypes

Class HelloWorldClass HelloWorld

MembersMembers

Method SayHelloMethod SayHello

StatementsStatements

ExpressionExpression

SystemSystem

CodeDOM graphCodeDOM graph

AssemblyAssembly

compilingcompilingCodeDOM graphCodeDOM graph

compilingcompilingsource codesource code

parsingparsingsource codesource code

generatinggeneratingsource codesource code

Page 13: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Assembly compilation

MotivationsOn-the-fly code generation and compilation

Interface interception

Compiled “scripting” support

Page 14: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

ICodeCompiler (1/3)

Compilation sourcesCodeCompileUnit (CodeDOM graph)Source fileString containing source code

Compilation methodsSingle compilationCompileAssemblyFromDom(…)CompileAssemblyFromFile(…)CompileAssemblyFromSource(…)

Batch compilationCompileAssemblyFromDomBatch(…)CompileAssemblyFromFileBatch(…)CompileAssemblyFromSourceBatch(…)

Page 15: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

ICodeCompiler (2/3)

Compilation parameterizationclass CompilerParameters

Compiler options

GenerateExecutable (false => dll)

GenerateInMemory

OutputAssembly

MainClass

Page 16: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

ICodeCompiler (3/3)

Compilation resultsCompileAssemblyFrom… methods return CompileResults

CompiledAssembly, Errors, Output, …

Printing the compiler output to the screen:

CompilerResults results = compiler.CompileAssemblyFromFile(options, src);

foreach (string line in results.Output) { Console.WriteLine(line); }

Page 17: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Generating Generating assemblies on the flyassemblies on the fly

demodemo

Page 18: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Agenda

CodeDOMIntroduction

Assembly compilation

Source code generation

Source code parsing

Advanced conceptsTemplate based source code generation

On-the-fly proxy generation

Page 19: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Source code generation

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

Source codeSource code

CompileUnitCompileUnit

NamespacesNamespaces

Namespace Sample Namespace Sample

ImportsImports TypesTypes

Class HelloWorldClass HelloWorld

MembersMembers

Method SayHelloMethod SayHello

StatementsStatements

ExpressionExpression

SystemSystem

CodeDOM graphCodeDOM graph

AssemblyAssembly

compilingcompilingCodeDOM graphCodeDOM graph

compilingcompilingsource codesource code

parsingparsingsource codesource code

generatinggeneratingsource codesource code

Page 20: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Source code generation

MotivationsAvoiding repetitive coding tasks

Generation of typed collections

Pattern based code generationTie pattern implementation

Implementation of language independent code wizards and tools

Designer support

Page 21: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

HelloWorld CodeDom graph

namespace Samples{ using System; public class Hello { public void SayHello() { Console.WriteLine("Hello World!"); } }}

CompileUnitCompileUnit

NamespacesNamespaces

Namespace Sample Namespace Sample

ImportsImports TypesTypes

Class HelloWorldClass HelloWorld

MembersMembers

Method SayHelloMethod SayHello

StatementsStatements

ExpressionExpression

SystemSystem

Page 22: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

CodeDom elements (1/3)

CodeObjectCommon base class for most CodeDOM objects

CodeCompileUnitContainer for a CodeDOM program graph

CodeCommentRepresents a comment

CodeExpressionBase class for other code expression objects:

CodeArrayCreateExpression

CodeCastExpression

CodeMethodInvokeExpression

Page 23: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

CodeDom elements (2/3)

CodeNamespaceRepresents a namespace declaration

CodeNamespaceImportRepresents a namespace import directive

CodeStatementBase class for other code statement objects:

CodeAssignStatement

CodeMethodReturnStatement

CodeIterationStatement

Page 24: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

CodeDom elements (3/3)

CodeTypeMemberBase class for a member of a type:

CodeMemberField

CodeMemberMethodCodeConstructor

CodeTypeConstructor (static ctor)

CodeEntryPointMethod

CodeMemberProperty

CodeTypeReferenceRepresents a reference to a type

Page 25: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

ICodeGenerator (1/3)

Generation sourcesCodeCompileUnit

CodeExpression

CodeNamespace

CodeStatement

CodeTypeDeclaration

Generation inputsCodeDOM element

TextWriter

Generation options

Page 26: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

ICodeGenerator (2/3)

Generation support verificationAre arrays of arrays supported?

Can I nest multiple types?

Are goto statements supported?

CodeDomProvider provider = new CodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider();Microsoft.CSharp.CSharpCodeProvider(); ICodeGenerator generator = provider.CreateGenerator();ICodeGenerator generator = provider.CreateGenerator(); if (generator.Supports(GeneratorSupport.NestedTypes) == false)if (generator.Supports(GeneratorSupport.NestedTypes) == false) {{ //we have a problem...//we have a problem... }}

Page 27: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

ICodeGenerator (3/3)

Generation optionsBlank lines between members

Bracing style (“Block” or “C”)

Else on closing

Indent string

CodeGeneratorOptions options = new CodeGeneratorOptions(); options.BlankLinesBetweenMembers = true; options.BracingStyle = "C"; // options.BracingStyle = “Block"; options.ElseOnClosing = true; options.IndentString = " ";

Page 28: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Generating source Generating source codecode

demodemo

Page 29: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Agenda

CodeDOMIntroduction

Assembly compilation

Source code generation

Source code parsing

Advanced conceptsTemplate based source code generation

On-the-fly proxy generation

Page 30: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Source code parsing

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

Source codeSource code

CompileUnitCompileUnit

NamespacesNamespaces

Namespace Sample Namespace Sample

ImportsImports TypesTypes

Class HelloWorldClass HelloWorld

MembersMembers

Method SayHelloMethod SayHello

StatementsStatements

ExpressionExpression

SystemSystem

CodeDOM graphCodeDOM graph

AssemblyAssembly

compilingcompilingCodeDOM graphCodeDOM graph

compilingcompilingsource codesource code

parsingparsingsource codesource code

generatinggeneratingsource codesource code

Page 31: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Source code parsing

MotivationsEnabling iterative designer/modeling support

Source code migrationPorting source code from one language into another

Page 32: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

There is only one problem…

CodeDomProvider csp = new Microsoft.CSharp.CSharpCodeProvider(); CodeDomProvider vbp = new Microsoft.VisualBasic.VBCodeProvider();

ICodeParser parser = csp.CreateParser(); ICodeGenerator generator = vbp.CreateGenerator();

CodeCompileUnit cu = parser.Parse(new StreamReader("Test.cs"));

generator.GenerateCodeFromCompileUnit(cu, new StreamWriter("Test.vb"),

new CodeGeneratorOptions());

Page 33: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

…and no real solution to it

Neither VB.NET, C# nor J# CodeDomProviders implement ICodeParser

Managed C++ implements ICodeParser, but it works only in the VS.NET designer scenario

Managed C++ implements a method based parser

Returns a CodeStatementCollection

Can’t be used for whole source files

Page 34: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Agenda

CodeDOMIntroduction

Assembly compilation

Source code generation

Source code parsing

Advanced conceptsTemplate based source code generation

On-the-fly proxy generation

Page 35: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

public class Listpublic class List{{ private object[] elements;private object[] elements; private int count;private int count;

public void Add(object element) {public void Add(object element) { if (count == elements.Length) Resize(count * 2);if (count == elements.Length) Resize(count * 2); elements[count++] = element;elements[count++] = element; }}

public object this[int index] {public object this[int index] { get { return elements[index]; }get { return elements[index]; } set { elements[index] = value; }set { elements[index] = value; } }}

public int Count {public int Count { get { return count; }get { return count; } }}}}

Problem statement

List intList = new List();List intList = new List();

intList.Add(1); // Argument is boxedintList.Add(1); // Argument is boxedintList.Add(2); // Argument is boxedintList.Add(2); // Argument is boxedintList.Add("Three"); // Should be an errorintList.Add("Three"); // Should be an error

int i = (int)intList[0]; // Cast requiredint i = (int)intList[0]; // Cast required

Page 36: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

A possible solution

public class public class IntListIntList{{ private private intint[] elements;[] elements; private int count;private int count;

public void Add(public void Add(intint element) { element) { if (count == elements.Length) Resize(count * 2);if (count == elements.Length) Resize(count * 2); elements[count++] = element;elements[count++] = element; }}

public public intint this[int index] { this[int index] { get { return elements[index]; }get { return elements[index]; } set { elements[index] = value; }set { elements[index] = value; } }}

public int Count {public int Count { get { return count; }get { return count; } }}}}

IntList intList = new IntList();IntList intList = new IntList();

intList.Add(1); // No boxingintList.Add(1); // No boxingintList.Add(2); // No boxingintList.Add(2); // No boxingintList.Add("Three"); // Compile-time errorintList.Add("Three"); // Compile-time error

int i = intList[0]; // No cast requiredint i = intList[0]; // No cast required

Page 37: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Template based source code generation

MotivationsAvoiding the generic approach

Downcasting/boxing is expensive

Type safety can’t be guaranteed

Base class can’t be chosen for a given implementation

class A : Immutableclass A : Immutableclass A : Volatileclass A : Volatile

All this (and more) will be addressed All this (and more) will be addressed through .NET Generics as well!through .NET Generics as well!

Page 38: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Generating parameterized types

CompileUnitCompileUnit

NamespacesNamespaces

Namespace Sample Namespace Sample

ImportsImports TypesTypes

Class HelloWorldClass HelloWorld

MembersMembers

Method SayHelloMethod SayHello

StatementsStatements

ExpressionExpression

SystemSystem

CollectionCollectiongraph graph

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

StringCollection StringCollection

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

Int32CollectionInt32Collection

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

FooCollection FooCollection

System.StringSystem.String

System.Int32System.Int32

Nonsense.FooNonsense.Foo

Page 39: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Implementation tips

Parameterize the creation of the CodeDOM graph

Types

Type names

Namespace names

CodeTypeDeclaration cs = new CodeTypeDeclaration(typeName);

CodeMemberField count = new CodeMemberField(type, "count");

CodeNamespace ns = new CodeNamespace(namespaceName);

Page 40: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Template based source Template based source code generationcode generation

demodemo

Page 41: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Agenda

CodeDOMIntroduction

Assembly compilation

Source code generation

Source code parsing

Advanced conceptsTemplate based source code generation

On-the-fly proxy generation

Page 42: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

On-the-fly proxy generation

MotivationsMethod call interception

Ensure thread safety

Logging/tracing

Tie-generationMaking an interface aware of the implementation context

Page 43: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Generating proxies

TypeType(Assembly(Assembly)) ProxyProxy

AssemblyAssembly

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

public static void Main(String[] args ){ String usr; FileStream f; StreamWriter w; try { usr=Environment.GetEnvironmentVariable("USERNAME"); f=new FileStream(“C:\\test.txt",FileMode.Create); w=new StreamWriter(f); w.WriteLine(usr); w.Close(); } catch (Exception e){ Console.WriteLine("Exception:"+e.ToString()); }}

Source Source

CompileUnitCompileUnitNamespacesNamespaces

Namespace Sample Namespace Sample ImportsImports TypesTypes

Class HelloWorldClass HelloWorldMembersMembersMethod SayHelloMethod SayHello

StatementsStatementsExpressionExpression

SystemSystem

Proxy Proxy graphgraph

ReflectionReflection

InjectionInjection GenerationGeneration

CompilationCompilation

CompileUnitCompileUnitNamespacesNamespaces

Namespace Sample Namespace Sample ImportsImports TypesTypes

Class HelloWorldClass HelloWorldMembersMembersMethod SayHelloMethod SayHello

StatementsStatementsExpressionExpression

SystemSystem

ReflectedReflected graph graph

Page 44: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Implementation tips (1/5)

Only type contracts are reflectableNo managed access to implementation

Intercept interfaces not classesSimplifies programming model

Generate constructors that initialize the underlying instance Be aware of unsupported constructs

Unsafe (string’s char*)Nested namespaces

Use IsSpecialName to detect property and event methods

Page 45: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Implementation tips (2/5)

Interface interception

public Interface IFoo{ int foo(int i);}

public class A : B, IFoo{ public A(string name){;} public int foo(int i){;} public int doIt(){;}}

public class Proxy : C, IFoo{ private A __tieObject; public Proxy(string name) { // pre ctor injection __tieObj = new A(name); // post ctor injection } public int foo(int i) { // pre method call injection int __returnValue; __returnValue = __tieObj.foo(i); // post method call injection return __returnValue; }}

Page 46: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Implementation tips (3/5)

Delegates and events allow flexible code injection

public delegate void MethodCallInjection(CodeMemberMethod mm, MethodInfo mi);

public delegate void CtorCallInjection(CodeConstructor cc, ConstructorInfo ci);

public delegate void PropertyCallInjection(CodeMemberProperty mp, PropertyInfo pi);

public event MethodCallInjection OnPreMethodCallInjection;public event MethodCallInjection OnMethodCallInjection;public event MethodCallInjection OnPostMethodCallInjection;

public event CtorCallInjection OnPreCtorCallInjection;…

Page 47: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Implementation tips (4/5)

Injection delegate implementationpublic void ParamCheckInjection(CodeMemberMethod mm, MethodInfo mi){ foreach (ParameterInfo pi in mi.GetParameters()) { mm.Statements.Add( new CodeExpressionStatement ( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodeTypeReferenceExpression("System.Console"),

"WriteLine”), new CodePrimitiveExpression(pi.Name + ": {0}"), new CodeMethodInvokeExpression(new CodeVariableReferenceExpression(pi.Name), "ToString")))); }} XmlNodeList SelectNodes(string xpath, XmlNamespaceManager nsmgr)

{ System.Console.WriteLine("xpath: {0}", xpath.ToString()); System.Console.WriteLine("nsmgr: {0}", nsmgr.ToString());

Page 48: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Implementation tips (5/5)

Creating an injected instance

public object CreateInstance(string typeName, params object[] args){ Type[] types = new Type[args.Length]; for (int i=0; i < args.Length; i++) { types[i] = args[i].GetType(); }

Type injectedType = compiledAssembly.GetType(typeName, true); ConstructorInfo ci = injectedType.GetConstructor(types); return ci.Invoke(args);}

IFoo iProxy = (IFoo) xxx.CreateInstance(“Proxy”, “Hello”);int s = iProxy.Foo(2);

Page 49: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

On-the-fly proxy On-the-fly proxy generationgeneration

demodemo

Page 50: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Agenda

CodeDOMIntroduction

Assembly compilation

Source code generation

Source code parsing

Advanced conceptsTemplate based source code generation

On-the-fly proxy generation

Summary

Page 51: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Summary

Assembly compilationOn-the-fly code generation and compilation

Source code generationAvoiding repetitive coding tasksPattern based code generationImplementation of language independent code wizards and tools

Source code parsingEnabling iterative designer/modeling supportSource code migration

Page 52: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Ask The ExpertsGet Your Questions Answered

I will be available in the ATE area after this session

Page 53: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

Community Resources

Community Resourceshttp://www.microsoft.com/communities/default.mspx

Most Valuable Professional (MVP)http://www.mvp.support.microsoft.com/

NewsgroupsConverse online with Microsoft Newsgroups, including Worldwidehttp://www.microsoft.com/communities/newsgroups/default.mspx

User GroupsMeet and learn with your peershttp://www.microsoft.com/communities/usergroups/default.mspx

Page 54: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

evaluationsevaluations

Page 55: DEV485.NET CodeDOM demystified Beat Schwegler Architect Evangelist.NET Developer Group Microsoft Corporation.

© 2003 Microsoft Corporation. All rights reserved.© 2003 Microsoft Corporation. All rights reserved.This presentation is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS SUMMARY.This presentation is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS SUMMARY.