NAVmoble - the pocket-sized ERP
Optimized for Microsoft Dynamics NAV and Windows Mobile powered devices

Monday, July 18, 2005

C# Code Generation with .NET - part 2

   This post is coming to wrap up the classes contained into the System.CodeDom namespace and the code snipsets from my previous post into a simple archtiecture for generating C# classes from Xml content.
Lets have the following class diagram:



Class XmlCodeGenerator provides a public method Generate.
It has the following declaration:



public class XmlCodeGenerator:IXmlCodeGenerator
{
   public IList Generate(XmlDocument xmlToMap, string targetFolder,string _namespace)
   {
....


XmlDocument contains the xml content, which should be processed.
targetFolder is the folder, where the source files will be generated.
_namespace is the root namespace for all new classes.
The method returns a list of the class names generated from the xml file.

The core of the code generation is implemented into the XmlNodeToClassMapper
descendant class.
XmlNodeToClassMapper is an abstract class and contains one abstract method:



public abstract class XmlNodeToClassMapper
{
public abstract System.CodeDom.CodeObject Map(XmlNode nodeToMap,params object[] parameters);
}


   The XmlCodeGenerator.Generate method iterates over the xml elements and
invokes the Map method of a ClassMapper instance for every xml element,
which have child xml elements or xm attributes. Xml elements without child elements or
xml attributes are mapped to members of the System.String type.

   The VS2003 solution for this sample may be downloaded here.
It contains the XmlCodeGenerator implementation, Unit Tests and sample Windows Application.

   Note that this sample is not meant to be a complete code generation solution. It is intended to illustrate
some of the .NET features, which may be used in code generation scenarios...

Sunday, July 17, 2005

C# Code Generation with .NET - part 1

Code generation tools are already standard equipment for the
developers these days.
The main motivation to use code generation techniques is that
most of theprojects share similar development tasks. It is
possibleto automate the execution these tasks by using special
tools -code generators.
The sample proposed here demonstrates some .NET features
for language independent code generation. The sample its self
should not be considered as a complete code generator
architecture.The development scenario, automated in this
sample is whenthe developer have a sample xml file, which
should be deserializedas a native .NET class , processed
somehow and serialized back to xml content.
The sample implements a class called XmlCodeGenerator,
which generates C# source files from given Xml file.Each
generated source file contains a C# class for each unique xml
element contained in the xml file. It automatically recognize if
the xml element should be mapped to as class or class member.
Due to the missing information about the actual data types all
xml elements mapped to simlpe class members are implemented
as System.String. Generated classes may be compiled and used
with System.Xml.Serialization.XmlSerializer class

If we have the following xml file:


<?xml version="1.0" encoding="utf-8" ?>
<employeeList>
<employee memberOf="Managers">
<names>Peter</names>
<birthDate>1.1.1967</birthDate>
<contact>
<town>Sofia</town>
<address>1000 Mladost</address>
<phone>0887435234</phone>
</contact>
</employee>
</employeeList>


XmlCodeGenerator will map the xml content to 3 classes in the
following way:

Xml element.NET class
employeeListEmployeeList
employeeEmployee
contactContact


The rest of the elements and attributes within the xml content
will be mapped as class members

This core functionality is wrapped around the System.CodeDom
name space. In general it contains classes that can be used to
represent the elements and structure of a source code document.
In order to create a .NET class declaration for the root xml element
"employeeList" we will have the following code:



uses Microsoft.CSharp;
uses System.CodeDom;
uses System.CodeDom.Compiler;
CodeTypeDeclaration classDeclaration = new CodeTypeDeclaration("EmployeeList");
classDeclaration.IsClass = true;
//make it public
constructor.Attributes= MemberAttributes.Public;
//add constructor
CodeConstructor constructor =
new CodeConstructor();
classDeclaration.Members.Add(constructor);
//add class level XmlRoot attribute
classDeclaration.CustomAttributes.Add(new CodeAttributeDeclaration("System.Xml.Serialization.XmlRoot",new CodeAttributeArgument(new CodePrimitiveExpression("employeeList"))));



Next, we should add some class members. In our case
"employeeList" element has one sub-element named
"emlpoyee". It will appear as a class member called Employee
of type Employee. The following code may be used to create
this class member:



uses Microsoft.CSharp;
uses System.CodeDom;
uses System.CodeDom.Compiler;
//create field
CodeMemberField field = new CodeMemberField("Employee","m_employee");
//embed field into the class declaration
classDeclaration.Members.Add(field)
//create property
CodeMemberProperty property = new CodeMemberProperty();
property.Name = "Employee";
property.Type = new CodeTypeReference("Employee");
property.Attributes = MemberAttributes.Public;
//add XmlElement attribute for serialziation support
property.CustomAttributes.Add(new CodeAttributeDeclaration("System.Xml.Serialization.XmlElement",new CodeAttributeArgument(new CodePrimitiveExpression("employee"))));
property.HasGet = true;
property.HasSet = true;
property.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),field.Name)));
property.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),field.Name), new CodePropertySetValueReferenceExpression()));
//embed property into the class declaration
classDeclaration.Members.Add(property)




Having this class declaration we have to generate the C# code.
We may do it by using the following code:


uses Microsoft.CSharp;
uses System.CodeDom;
uses System.CodeDom.Compiler;
//obtain C# code provider
CSharpCodeProvider provider = new CSharpCodeProvider();
//get the proper code generator
.ICodeGenerator generator = provider.CreateGenerator();
//create namespace to place our class declaration into
CodeNamespace _namespace = new CodeNamespace(Namespace);
_namespace.Types.Add((CodeTypeDeclaration)classDeclaration);
//generate code
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BlankLinesBetweenMembers = true;
System.IO.StreamWriter sw = System.IO.File.CreateText("D:\\work\\employeeList.cs");
generator.GenerateCodeFromNamespace(_namespace,sw,options)
sw.Close();



As you may see having this type of class declaration our code
generator is not limited to C# code generation only.

Let's wrap up these code snipsets...To be continued

Monday, July 11, 2005

RSS in Longhorn

More info about the announced support for RSS in Longhorn may be found here

The Longhorn RSS platform consists of three parts:

  • RSS Feed List
    Provide access to the feeds to which the user is subscribed
  • RSS Data Store
    Provide access through an object model to the downloaded feeds and enclosures
  • RSS Platform Sync Engine
    Service, which automatically downloads feed content and enclosures

  • Hopefully, the platform architecture is designed to be easy accessible from RSS enabled application.

    Some demos may be found here

    Tuesday, July 05, 2005

    The Open Source Heretic

    Which one is better : Open-source or traditional software business model?

    Some interesting thoughts may arise if you read The Open Source Heretic
    article form Larry McVoy

    Design Patterns used in .NET

    I found another interesting article via the Moth

    Design Patterns used in the framework

    Friday, July 01, 2005

    CF vs Full .NET

    Another good document about the differences between CF and Full .NET Framework may be found here

    The following article gives some good advices for Writing High-Performance Managed Applications
    These hints may be used in the CF as well.

    Compact Framework Architecture

    I found an interesting document discussing internal differences between the full .NET framework an the Compact Framework.

    It may be found here - Compact Framework Architecture