Entity classes are the pillars for building a solid business layer of the application. An Entity class enables you to create objects and collections which can interact with other objects and collections. They provide the interface for the true object oriented programming. The downside of creating the Entity Classes is that they require a lot of code to be written. Most of the code is repetitive and involves creating the private fields and exposing them as pubic properties. In this article we will see that how you can minimize this work by creating a very simple code generator application by using the classes defined in the CodeDom namespace.
Entity classes are the pillars
for building a solid business layer of the application. An Entity class enables
you to create objects and collections which can interact with other objects and
collections. They provide the interface for the true object oriented
programming. The downside of creating the Entity Classes is that they require a
lot of code to be written. Most of the
code is repetitive and involves creating the private fields and exposing them
as pubic properties. In this article we will see that how you can minimize this
work by creating a very simple code generator application by using the classes
defined in the CodeDom namespace.
This article is focused
on generating the code using the CodeDom namespace. In this article you will write a console
application which will generate the Entity Classes which will be mapped to the
tables in your database.
Creating the NameSpace:
The first step in
generating the Entity Class is to generate a namespace. CodeDom provides an
easy way to declare your custom namespace. Take a look at the InitializeNameSpace method below which creates the
custom namespace.
private CodeNamespace
InitializeNameSpace(string name) { CodeNamespace
currentNameSpace = new CodeNamespace(name); currentNameSpace.Imports.Add(new CodeNamespaceImport("System")); currentNameSpace.Imports.Add(new CodeNamespaceImport("System.Text")); return
currentNameSpace; } |
The CodeNamespace
class is responsible for creating the
namespaces. The name passed to the InitializeNameSpace method contains the name for the namespace which is to be
created. The Add method of the Imports class of CodeNameSpace is responsible
for adding multiple namespaces. In the code above I have added two namespaces
namely System and System.Text.
Creating
the Class:
The next step is to create the class. The CodeTypeDeclaration object in the CodeDom namespace is responsible for creating
classes. Take a look at the CreateClass method
below which generates the code for creating the class.
private CodeTypeDeclaration CreateClass(string name) { CodeTypeDeclaration
ctd = new CodeTypeDeclaration(name); ctd.IsClass = true; ctd.Attributes = MemberAttributes.Public; return
ctd; } |
Creating Fields and Properties:
Creating the fields and
properties is a little tricky. For fields you need to use the CodeMemberField object. In order to map the fields
to the database columns you need to get the schema of the table. This can be
done easily by filling the DataSet with the schema of the database table. The
SqlDataAdapter object’s Fill method will fill the DataSet with the table
schema. Take a look at the code below:
public static DataSet GetDataSet(string
databaseName, string tableName) { string
connectionString = GetConnectionString(databaseName); string
query = "SELECT * FROM " +
tableName; SqlConnection
myConnection = new SqlConnection(connectionString); SqlDataAdapter
ad = new SqlDataAdapter(query,
myConnection); DataSet
ds = new DataSet(); ad.FillSchema(ds, SchemaType.Mapped,tableName); return
ds; } |
The GetDataSet method takes the database name
and the table name as the two parameters and on those bases it gets the schema
of the table in the database.
Now, let’s see how the fields
and the properties are created.
private void CreateFields(CodeTypeDeclaration ctd) { DataSet
ds = DatabaseHelper.GetDataSet(DatabaseName,TableName); foreach
(DataColumn dc in
ds.Tables[0].Columns) { ctd.Members.Add(new CodeMemberField(dc.DataType.ToString() ,FormatFieldNameFromColumnName(dc.ColumnName))); CodeMemberProperty
property = new CodeMemberProperty(); property.Attributes = MemberAttributes.Public; property.Name = dc.ColumnName; property.Type = new CodeTypeReference(dc.DataType); property.HasGet = true; property.HasSet = true; property.GetStatements.Add(new CodeMethodReturnStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(),
FormatFieldNameFromColumnName(dc.ColumnName)))); property.SetStatements.Add(new CodeAssignStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), FormatFieldNameFromColumnName( dc.ColumnName)), new CodePropertySetValueReferenceExpression())); ctd.Members.Add(property); } } |
As, you can see once you
get the DataSet which contains the schema of the table you iterate through the
columns and creates the fields which are represented by column names. The
properties are created by using the CodeMemberProperty object. The CodeMemberProperty
object has the SetStatements and GetStatments
properties which represents the setter and getter methods of a property.
Finally,
it is time to generate the code. The GenerateCode method given below is
responsible for generating the code. The CSharpCodeProvider is responsible for generating the
code in the C# language. You can use the VBCodeProvider to generate the code in VB.
public string GenerateCode() { CodeGeneratorOptions
options = new CodeGeneratorOptions(); options.BracingStyle = "C"; options.IndentString = " "; StringBuilder
sbCode = new StringBuilder(); StringWriter
sw = new StringWriter(sbCode); this.currentNameSpace.Types.Add(this.currentClass); CSharpCodeProvider
provider = new CSharpCodeProvider(); provider.GenerateCodeFromNamespace(this.currentNameSpace, sw, options); return
sbCode.ToString(); } |
This article gives you a very brief introduction to the
CodeDom namespace and how it can be used to generate code.
I hope you liked the article happy coding!
Download the complete code sample using the link below.