|
|||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionASP.NET is a great managed environment that supports dynamic compilation for its registered resources. The aim of this article is to show how one can take advantage of dynamic compilation through the use of custom build providers. The BuildProvider ClassThe This list outlines how the ASP.NET build environment uses your instance of
To find out more about the A ZipCode BuildProviderThis article uses a simple build provider that parses a file containing zip code information. The provider creates a state class for each line in the file and exposes the zip codes as properties. The custom file and the generated class look like this: Contents of file All.zipcode: Iowa|IA|50311;51442;50111;50021;50023
Nebraska|NE|12345;67890
Texas|TX|99999;12345
Generated state class:
As previously stated, the provider must be registered within web.config in order for the runtime to hook up your provider. The entry for the <buildProviders>
<add appliesTo="Code"
extension=".zipCode"
type="Lozanotek.Examples.ZipCodeBuildProvider, BuildProvider"/>
</buildProviders>
In order to generate source code that will be compiled into an assembly, you must make use of the classes under the /// <summary>
/// Creates a class by parsing the given line
/// </summary>
/// <param name="line">Line to parse</param>
/// <returns>A class declaration for a custom state class</returns>
private CodeTypeDeclaration CreateClass(string line)
{
// Parse out the tokens
string[] values = line.Split(new string[1] { "|" },
StringSplitOptions.RemoveEmptyEntries);
// Set the name of the class
string className = values[0];
CodeTypeDeclaration cls = new CodeTypeDeclaration(className);
// Set an internal field and its value
string fieldName = values[1];
CodeMemberField abbrField = CreateField(fieldName);
cls.Members.Add(abbrField);
// Get the zip codes listed for the states
string[] zipCodes = values[2].Split(new string[1] { ";" },
StringSplitOptions.RemoveEmptyEntries);
// Create a property for each of the zip codes found
foreach (string zipCode in zipCodes)
{
string tempZip = zipCode.Trim();
CodeMemberField zipField = CreateField(tempZip);
CodeMemberProperty zipProperty = CreateProperty(tempZip);
cls.Members.Add(zipField);
cls.Members.Add(zipProperty);
}
return cls;
}
/// <summary>
/// Creates a private string field to store the value for the zip code
/// </summary>
/// <param name="fieldName">Name of the fild to create</param>
/// <returns>A unit representing an private string field</returns>
private CodeMemberField CreateField(string fieldName)
{
// Specify that you want to create a string field with the given name
CodeMemberField field = new CodeMemberField(typeof(String),
string.Format("_{0}", fieldName));
// Make the field private and static
field.Attributes = MemberAttributes.Private | MemberAttributes.Static;
// Assign the value of the field to the zip code
field.InitExpression =
new CodeSnippetExpression(string.Format("\"{0}\"", fieldName));
return field;
}
/// <summary>
/// Creates a property that returns the value of a string field
/// </summary>
/// <param name="propertyName">Name of the property to create</param>
/// <returns>A unit representing a public static property</returns>
private CodeMemberProperty CreateProperty(string propertyName)
{
CodeMemberProperty prop = new CodeMemberProperty();
prop.Name = string.Format("zip{0}", propertyName);
prop.Type = new CodeTypeReference(typeof(String));
prop.Attributes = MemberAttributes.Public | MemberAttributes.Static;
// Build the body of the property by assigning it a get statement
prop.GetStatements.Add(new CodeMethodReturnStatement(
new CodeFieldReferenceExpression(null,
string.Format("_{0}", propertyName))));
return prop;
}
ConclusionI hope this article has shown you, the developer, how to take advantage of the extensibility of the ASP.NET runtime. In my next Extending ASP.NET 2.0 article, I will demonstrate how to extend ASP.NET even further by creating custom expression builders. Please feel free to make any comments or suggestions to this article by using the forums below. ReferencesDuring the writing of this article, I used the following resources:
|
||||||||||||||||||||||||||||||||