Power Tools for the  Modern Programmer Regular Expressions, Reflection, Code Generation
Introduction  Leverage advanced practices to build adaptive business solutions Boost your own productivity by reducing repetitive tedious code Improve quality and consistency by reducing repetitive error prone code
What We Will Cover Power Tools Sample Application Further Ideas Sources for More Information
Power Tools Regular expressions  Take string manipulation to the next level Reflection  Interrogate and manipulate code metadata at run time Code generation  Make the computer write its own code Design patterns Leverage best practices in your designs
Overview - Reflection Create adaptive solutions Simplify code complexity Ease maintenance Ease deployment Solve configuration management issues
Overview Regular Expressions Regular expressions are to string as math is to numbers Simplify and optimize string manipulation Use editing tools to simplify creating regular expressions Document!  Document!  Document!
Overview Code Generation Obtain language independence with the CodeDom Use meta data to drive the code generation  Use meta data to provide code documentation Standardize repetitive tasks with consistent implementation
Overview Patterns Leverage emerging best practices Leverage existing documentation Don’t go over board The KISS Principle still applies
Sample Problem Parse fixed length record file Parse with multiple purposes at different times (Load in a database, display on a document, display in a web page, etc) Need to parse multiple file with different formats
Sample Format Customer order tracking file Customer Record Order Record Order Item Record Address Record
Customer CST Record Identifer 23  Characters Customer ID 25  Characters First Name 25 Characters Last Name 3 Characters Age
Order Record ODR Record Identifier 8 Characters Order Date 8 Characters Required Date 8 Characters Shipped Date
Order Item Record ITM Record Identifier 25 Characters Product ID 5 Characters Quantity 5 Characters Unit Price 4 Characters Discount
Address Record ADR Record Identifier 60 Characters Street Address 75 Characters City 2 Characters State 5 Characters Zip Code 4 Characters Zip Plus 4
Very Easy Regular Expression “ CST(?<CustomerID>.{23} (?<FirstName>.{25}) (?<LastName>.{25}) (?<Age>.{3})”
Regular Expression Notes Verify that the input string starts as expected Allow any character for the specified number of times Use named explicit capture groups
Defining Record Objects Define a Constructor expecting a string to parse Define read only strongly typed property for each element in the record
Building the Record Object Metadata storage Generation Process Provide documentation
Metadata
Generation Process CodeNamespace CodeTypeDeclaration CodeConstructor CodeMemberProperty CodeMemberMethod CodeVariableDeclaration CodeAssignmentStatement
Documentation Process Simple reports Documentation is accurate because it drives program execution
Reflection to Reduce Complexity One measure of complexity is the number of paths through the code Multiple paths may lead to redundant code Multiple paths may lead to confusing flow control Multiple paths may lead to higher maintenance requirements
Identifying Record Objects  (Hard Coded) Separate case statement for each record type Brittle dependency on the file format More complex formats lead to more complex parsing Parsing a different format requires a different parser
private void HardCodedParseLine (string inputLine) { string prefix = inputLine.Substring (0,3); object parsedObject = null; switch (prefix) {   case &quot;CST&quot;:   { parsedObject = new Customer (inputLine); break;   }   case &quot;ODR&quot;:   { parsedObject = new Order (inputLine); break;   }   . . . } DisplayObjectDetails (parsedObject, tvwResults); }
Identifying Record Objects  (Reflective) Single path through the code Code complexity stays constant even as file format complexity increases Same parser can handle parsing files with different formats
private void ReflectiveParseLine (string inputLine) { string prefix = inputLine.Substring (0,3); Type parseType = (Type)mTypes[prefix]; Object [] parameters = {inputLine}; if (parseType != null) { object parseObject = Activator.CreateInstance  (parseType, parameters); Common.Helpers.DisplayObjectDetails  (parseObject, tvwResults); } }
Visitor Pattern Create enhanced flexibility with events Define an event that will be raised when a record object is identified Calling objects “visit” each discovered object by subscribing to the event Separation of responsibilities Parser knows how to identify record objects but not what to do with them Visitors know what to do with the record objects but not how to find them
Further Ideas Load the Record Object types through reflection or from a config file instead of hard coding them into hash table Use reflection to identify the method to be called from the event handler specific to each record object type Generate and compile the record objects at run time for the ultimate in flexibility
Sources for More Information Reflection http://www.oreillynet.com/pub/au/1073 Regular Expressions http://www.ultrapico.com/Expresso.htm http://weblogs.asp.net/rosherove/articles/6863.aspx Code Generation http://www.ondotnet.com/pub/a/dotnet/2003/02/03/codedom.html

Developer power tools

  • 1.
    Power Tools forthe Modern Programmer Regular Expressions, Reflection, Code Generation
  • 2.
    Introduction Leverageadvanced practices to build adaptive business solutions Boost your own productivity by reducing repetitive tedious code Improve quality and consistency by reducing repetitive error prone code
  • 3.
    What We WillCover Power Tools Sample Application Further Ideas Sources for More Information
  • 4.
    Power Tools Regularexpressions Take string manipulation to the next level Reflection Interrogate and manipulate code metadata at run time Code generation Make the computer write its own code Design patterns Leverage best practices in your designs
  • 5.
    Overview - ReflectionCreate adaptive solutions Simplify code complexity Ease maintenance Ease deployment Solve configuration management issues
  • 6.
    Overview Regular ExpressionsRegular expressions are to string as math is to numbers Simplify and optimize string manipulation Use editing tools to simplify creating regular expressions Document! Document! Document!
  • 7.
    Overview Code GenerationObtain language independence with the CodeDom Use meta data to drive the code generation Use meta data to provide code documentation Standardize repetitive tasks with consistent implementation
  • 8.
    Overview Patterns Leverageemerging best practices Leverage existing documentation Don’t go over board The KISS Principle still applies
  • 9.
    Sample Problem Parsefixed length record file Parse with multiple purposes at different times (Load in a database, display on a document, display in a web page, etc) Need to parse multiple file with different formats
  • 10.
    Sample Format Customerorder tracking file Customer Record Order Record Order Item Record Address Record
  • 11.
    Customer CST RecordIdentifer 23 Characters Customer ID 25 Characters First Name 25 Characters Last Name 3 Characters Age
  • 12.
    Order Record ODRRecord Identifier 8 Characters Order Date 8 Characters Required Date 8 Characters Shipped Date
  • 13.
    Order Item RecordITM Record Identifier 25 Characters Product ID 5 Characters Quantity 5 Characters Unit Price 4 Characters Discount
  • 14.
    Address Record ADRRecord Identifier 60 Characters Street Address 75 Characters City 2 Characters State 5 Characters Zip Code 4 Characters Zip Plus 4
  • 15.
    Very Easy RegularExpression “ CST(?<CustomerID>.{23} (?<FirstName>.{25}) (?<LastName>.{25}) (?<Age>.{3})”
  • 16.
    Regular Expression NotesVerify that the input string starts as expected Allow any character for the specified number of times Use named explicit capture groups
  • 17.
    Defining Record ObjectsDefine a Constructor expecting a string to parse Define read only strongly typed property for each element in the record
  • 18.
    Building the RecordObject Metadata storage Generation Process Provide documentation
  • 19.
  • 20.
    Generation Process CodeNamespaceCodeTypeDeclaration CodeConstructor CodeMemberProperty CodeMemberMethod CodeVariableDeclaration CodeAssignmentStatement
  • 21.
    Documentation Process Simplereports Documentation is accurate because it drives program execution
  • 22.
    Reflection to ReduceComplexity One measure of complexity is the number of paths through the code Multiple paths may lead to redundant code Multiple paths may lead to confusing flow control Multiple paths may lead to higher maintenance requirements
  • 23.
    Identifying Record Objects (Hard Coded) Separate case statement for each record type Brittle dependency on the file format More complex formats lead to more complex parsing Parsing a different format requires a different parser
  • 24.
    private void HardCodedParseLine(string inputLine) { string prefix = inputLine.Substring (0,3); object parsedObject = null; switch (prefix) { case &quot;CST&quot;: { parsedObject = new Customer (inputLine); break; } case &quot;ODR&quot;: { parsedObject = new Order (inputLine); break; } . . . } DisplayObjectDetails (parsedObject, tvwResults); }
  • 25.
    Identifying Record Objects (Reflective) Single path through the code Code complexity stays constant even as file format complexity increases Same parser can handle parsing files with different formats
  • 26.
    private void ReflectiveParseLine(string inputLine) { string prefix = inputLine.Substring (0,3); Type parseType = (Type)mTypes[prefix]; Object [] parameters = {inputLine}; if (parseType != null) { object parseObject = Activator.CreateInstance (parseType, parameters); Common.Helpers.DisplayObjectDetails (parseObject, tvwResults); } }
  • 27.
    Visitor Pattern Createenhanced flexibility with events Define an event that will be raised when a record object is identified Calling objects “visit” each discovered object by subscribing to the event Separation of responsibilities Parser knows how to identify record objects but not what to do with them Visitors know what to do with the record objects but not how to find them
  • 28.
    Further Ideas Loadthe Record Object types through reflection or from a config file instead of hard coding them into hash table Use reflection to identify the method to be called from the event handler specific to each record object type Generate and compile the record objects at run time for the ultimate in flexibility
  • 29.
    Sources for MoreInformation Reflection http://www.oreillynet.com/pub/au/1073 Regular Expressions http://www.ultrapico.com/Expresso.htm http://weblogs.asp.net/rosherove/articles/6863.aspx Code Generation http://www.ondotnet.com/pub/a/dotnet/2003/02/03/codedom.html