Telerik OpenAccess ORM uses a set of templates to generate classes from a database schema. These templates are nothing special but class definitions with a lot of placeholders that are being replaced with real values to produce buildable source code. Using templates gives us the ability to fully customize our reverse mapped classes.
I am going to demonstrate how we can edit the templates so the generated classes will implement the INotifyPropertyChanging and INotifyPropertyChanged interfaces. All class-generating templates take place in the “C:\Program Files\Telerik\OpenAccess ORM\sdk\IDEIntegrations\templates\PCClassGeneration” directory. Navigate to it and open the “default.vm” file under the “\cs\templates\classgen\class” subfolder. This template is used for generating nonpartial classes (you can enable/disable the option for generating partial classes from the Reverse mapping wizard -> Options). The file has the following content by default:
#if($hasErrors)//***Telerik OpenAccess - Reverse Engineering errors***#end
#foreach($error in $errors)#error $error#end#end
using System;
using System.Collections.Generic;
#foreach( $import in $imports )${import}#end
#if(${hasPackage})namespace ${classPackage}
{#end
// Generated by Telerik OpenAccess
// Used template: $usedTemplate
[Telerik.OpenAccess.Persistent#if($multipleField)(Identity=typeof(#end#if($multipleField && $hasPackage)$classPackage.#end#if($multipleField)$className.ID))#end#if($singleField)(IdentityField="$(pkField)")#end]
public class $className
{
#foreach( $variableDeclaration in $allVariableDeclaration )$variableDeclaration#end
public $className()
{
}
#foreach( $variableAccess in $allVariableAccess )$variableAccess #end
#if ($multipleField)$objectIdentity#end
}
#if(${hasPackage})}#end
As you can see, the specific syntax is represented by conditional statements, cycles and variables marked with ‘$’ at the beginning. The rest of the code is exactly what you get in the class.
So, what we have to do in this file is just make the class implement the desired interfaces. The new code is colored in red below:
#if($hasErrors)//***Telerik OpenAccess - Reverse Engineering errors***#end
#foreach($error in $errors)#error $error#end#end
using System;
using System.Collections.Generic;
using System.ComponentModel;
#foreach( $import in $imports )${import}#end
#if(${hasPackage})namespace ${classPackage}
{#end
// Generated by Telerik OpenAccess
// Used template: $usedTemplate
[Telerik.OpenAccess.Persistent#if($multipleField)(Identity=typeof(#end#if($multipleField && $hasPackage)$classPackage.#end#if($multipleField)$className.ID))#end#if($singleField)(IdentityField="$(pkField)")#end]
public class $className : INotifyPropertyChanging, INotifyPropertyChanged
{
#foreach( $variableDeclaration in $allVariableDeclaration )$variableDeclaration#end
public $className()
{
}
//INotifyPropertyChanging Members
public event PropertyChangingEventHandler PropertyChanging;
protected virtual void OnPropertyChanging(string propertyName)
{
if (this.PropertyChanging != null)
this.PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
//INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#foreach( $variableAccess in $allVariableAccess )$variableAccess #end
#if ($multipleField)$objectIdentity#end
}
#if(${hasPackage})}#end
The second step is to edit the file that generates the properties of a class. This file is located at the “\cs\templates\classgen\fields\field\access” folder and is also named “default.vm”. We have to make sure that the relevant events are fired when a property changes. Just add the two lines in red and save the file:
[Telerik.OpenAccess.FieldAlias("$(fieldName)")]
public $fieldType#if($isNullable)?#end#if($isArrayType)[]#end $fieldNameCaps
{
get { return $fieldName; }
set
{
OnPropertyChanging("$(fieldNameCaps)");
this.$fieldName = value;
OnPropertyChanged("$(fieldNameCaps)");
}
}
Now when we generate nonpartial classes with the Reverse mapping wizard, these classes will automatically implement the INotifyPropertyChanging and INotifyPropertyChanged interfaces. Of course, you can edit the templates as you would like and implement any functionality that your applications require. Just be careful, there is a big chance to end up with uncompilable code if you are not sure what you are doing. It is always good to have a back up with the default templates in case something goes wrong.
The working templates from this demo can be found here in our Code library. VB.NET and C# versions are included for generating both single-file and partial classes.