MSDN Magazine - February 2009 - (Page 40) Generally, though, software developers do not have absolute control over programming languages. While I definitely think that we should take advantage of new programming language innovations or even alternative languages, it’s time to talk about design ideas that you can use today with mainstream C# and Visual Basic. Say It Once and Only Once What happens when you find out midway through a project that something about the definition of a single data field needs to be changed? In far too many cases, that small change to the database will ripple through your application as you make an analogous change to various parts of the middle tier, data access code, and even into the user interface layer in order to accommodate a single logical change. At a past employer, we called that rippling effect from small data field changes the Wormhole Anti-Pattern. You want to get away from the need for a small change in one place being teleported all through the layers. You can slow down the wormhole effect by reducing unnecessary layering, and that’s the first step. The harder but more rewarding step is to find a way to say it once and only once. The Say It Once and Only Once Principle states that there should only be a single authoritative source for any fact or policy in the system as a whole. Let’s take the example of building a Web appliFigure 2 Using Validation Attributes public class Address : DomainEntity { [Required, MaximumStringLength(250)] public string Address1 { get; set; } [Required, MaximumStringLength(250)] public string City { get; set; } [Required] public string StateOrProvince { get; set; } [Required, MaximumStringLength(100)] public string Country { get; set; } [Required, MaximumStringLength(50)] public string PostalCode { get; set; } } public string TimeZone { get; set; } Figure 3 Handling Attributes in NHibernate public class MyPersistenceModel : PersistenceModel { public MyPersistenceModel() { // If a property is marked with the [Required] // attribute, make the corresponding column in // the database "NOT NULL" Conventions.ForAttribute ((att, prop) => { if (prop.ParentIsRequired) { prop.SetAttribute("not-null", "true"); } }); // Uses the value from the [MaximumStringLength] // attribute on a property to set the length of // a string column in the database Conventions.ForAttribute ((att, prop) => { prop.SetAttribute("length", att.Length.ToString()); }); cation with create, read, update, and delete (CRUD) functionality. This kind of system is largely concerned with editing and storing data fields. These fields need to be edited in screens, validated on the server, stored in the database, and hopefully validated on the client as well for a better user experience—but you’d like to specify that “this field is required and/or this field must be no more than 50 characters” in the code only once. There are a couple of different approaches you could take. You could make the database schema the master definition and generate both middle-tier and user-presentation code from the schema. You could also define the data fields in some sort of external metadata storage such as an XML file, then use code generation to build the database schema, any middle-tier objects, and the user interface screens. Personally, I’m not a fan of large-scale code generation, so my team chose another direction. We generally design the domain model classes first, and we consider the validation logic to be the responsibility of the domain model entity classes. For simple validation rules such as required fields and maximum string length rules, we decorate properties with validation attributes such as the Address class shown in Figure 2. Using attributes is a simple and fairly common technique in order to specify validation rules. You are also able to say that since the validation rules are expressed declaratively instead of implemented with imperative code, you have passed the essence-versus-ceremony test. Now, though, you need to replicate the rules for required fields and maximum string lengths to the database. In my team’s case, we use NHibernate for our persistence mechanism. One of the powerful capabilities of NHibernate is to generate data definition language (DDL) code from the NHibernate mappings that you can then use to create the database schema and keep it in sync with the domain model (this strategy obviously works best in new projects). In order for this strategy of generating the database from the domain model to be useful, it was necessary for us to add additional information to the NHibernate mappings to mark non-null fields and specify string lengths. We used the new Fluent NHibernate mechanism to define our object mappings. In our setup code for Fluent NHibernate, we established automatic conventions in the mapping by teaching Fluent NHibernate how to handle the presence of the [Required] and [MaximumStringLength] attributes in our model classes with the code shown in Figure 3. These conventions will now be applied to all mappings in the project. For the Address class, I simply tell Fluent NHibernate which properties are persisted: public class AddressMap : DomainMap { public AddressMap() { Map(a => a.Address1); Map(a => a.City); Map(a => a.TimeZone); Map(a => a.StateOrProvince); Map(a => a.Country); Map(a => a.PostalCode); } } } } Now that I’ve taught Fluent NHibernate about the validation attributes, I can generate the DDL for the Address table (see Figure Patterns in Practice 40 msdn magazine
Table of Contents Feed for the Digital Edition of MSDN Magazine - February 2009 MSDN Magazine - February 2009 Contents Toolbox CLR Inside Out Data Points Cutting Edge Patterns In Practice Best Practices .Net Interop "Oslo" Basics Patterns Silverlight Under The Table Foundations Windows With C++ .NET Matters Going Places { End Bracket } MSDN Magazine - February 2009 MSDN Magazine - February 2009 - (Page Splash1) MSDN Magazine - February 2009 - Contents (Page Cover1) MSDN Magazine - February 2009 - Contents (Page Cover2) MSDN Magazine - February 2009 - Contents (Page 1) MSDN Magazine - February 2009 - Contents (Page 2) MSDN Magazine - February 2009 - Contents (Page 3) MSDN Magazine - February 2009 - Contents (Page 4) MSDN Magazine - February 2009 - Contents (Page 5) MSDN Magazine - February 2009 - Contents (Page 6) MSDN Magazine - February 2009 - Contents (Page 7) MSDN Magazine - February 2009 - Contents (Page 8) MSDN Magazine - February 2009 - Contents (Page 9) MSDN Magazine - February 2009 - Contents (Page 10) MSDN Magazine - February 2009 - Toolbox (Page 11) MSDN Magazine - February 2009 - Toolbox (Page 12) MSDN Magazine - February 2009 - Toolbox (Page 13) MSDN Magazine - February 2009 - Toolbox (Page 14) MSDN Magazine - February 2009 - CLR Inside Out (Page 15) MSDN Magazine - February 2009 - CLR Inside Out (Page 16) MSDN Magazine - February 2009 - CLR Inside Out (Page 17) MSDN Magazine - February 2009 - CLR Inside Out (Page 18) MSDN Magazine - February 2009 - CLR Inside Out (Page 19) MSDN Magazine - February 2009 - CLR Inside Out (Page 20) MSDN Magazine - February 2009 - CLR Inside Out (Page 21) MSDN Magazine - February 2009 - CLR Inside Out (Page 22) MSDN Magazine - February 2009 - Data Points (Page 23) MSDN Magazine - February 2009 - Data Points (Page 24) MSDN Magazine - February 2009 - Data Points (Page 25) MSDN Magazine - February 2009 - Data Points (Page 26) MSDN Magazine - February 2009 - Data Points (Page 27) MSDN Magazine - February 2009 - Data Points (Page 28) MSDN Magazine - February 2009 - Data Points (Page 29) MSDN Magazine - February 2009 - Data Points (Page 30) MSDN Magazine - February 2009 - Cutting Edge (Page 31) MSDN Magazine - February 2009 - Cutting Edge (Page 32) MSDN Magazine - February 2009 - Cutting Edge (Page 33) MSDN Magazine - February 2009 - Cutting Edge (Page 34) MSDN Magazine - February 2009 - Cutting Edge (Page 35) MSDN Magazine - February 2009 - Cutting Edge (Page 36) MSDN Magazine - February 2009 - Cutting Edge (Page 37) MSDN Magazine - February 2009 - Cutting Edge (Page 38) MSDN Magazine - February 2009 - Patterns In Practice (Page 39) MSDN Magazine - February 2009 - Patterns In Practice (Page 40) MSDN Magazine - February 2009 - Patterns In Practice (Page 41) MSDN Magazine - February 2009 - Patterns In Practice (Page 42) MSDN Magazine - February 2009 - Patterns In Practice (Page 43) MSDN Magazine - February 2009 - Patterns In Practice (Page 44) MSDN Magazine - February 2009 - Patterns In Practice (Page 45) MSDN Magazine - February 2009 - Best Practices (Page 46) MSDN Magazine - February 2009 - Best Practices (Page 47) MSDN Magazine - February 2009 - Best Practices (Page 48) MSDN Magazine - February 2009 - Best Practices (Page 49) MSDN Magazine - February 2009 - Best Practices (Page 50) MSDN Magazine - February 2009 - Best Practices (Page 51) MSDN Magazine - February 2009 - Best Practices (Page 52) MSDN Magazine - February 2009 - Best Practices (Page 53) MSDN Magazine - February 2009 - Best Practices (Page 54) MSDN Magazine - February 2009 - Best Practices (Page 55) MSDN Magazine - February 2009 - Best Practices (Page 56) MSDN Magazine - February 2009 - .Net Interop (Page 57) MSDN Magazine - February 2009 - .Net Interop (Page 58) MSDN Magazine - February 2009 - .Net Interop (Page 59) MSDN Magazine - February 2009 - .Net Interop (Page 60) MSDN Magazine - February 2009 - .Net Interop (Page 61) MSDN Magazine - February 2009 - .Net Interop (Page 62) MSDN Magazine - February 2009 - "Oslo" Basics (Page 63) MSDN Magazine - February 2009 - "Oslo" Basics (Page 64) MSDN Magazine - February 2009 - "Oslo" Basics (Page 65) MSDN Magazine - February 2009 - "Oslo" Basics (Page 66) MSDN Magazine - February 2009 - "Oslo" Basics (Page 67) MSDN Magazine - February 2009 - "Oslo" Basics (Page 68) MSDN Magazine - February 2009 - "Oslo" Basics (Page 69) MSDN Magazine - February 2009 - "Oslo" Basics (Page 70) MSDN Magazine - February 2009 - "Oslo" Basics (Page 71) MSDN Magazine - February 2009 - Patterns (Page 72) MSDN Magazine - February 2009 - Patterns (Page 73) MSDN Magazine - February 2009 - Patterns (Page 74) MSDN Magazine - February 2009 - Patterns (Page 75) MSDN Magazine - February 2009 - Patterns (Page 76) MSDN Magazine - February 2009 - Patterns (Page 77) MSDN Magazine - February 2009 - Patterns (Page 78) MSDN Magazine - February 2009 - Patterns (Page 79) MSDN Magazine - February 2009 - Patterns (Page 80) MSDN Magazine - February 2009 - Patterns (Page 81) MSDN Magazine - February 2009 - Patterns (Page 82) MSDN Magazine - February 2009 - Patterns (Page 83) MSDN Magazine - February 2009 - Silverlight (Page 84) MSDN Magazine - February 2009 - Silverlight (Page 85) MSDN Magazine - February 2009 - Silverlight (Page 86) MSDN Magazine - February 2009 - Silverlight (Page 87) MSDN Magazine - February 2009 - Silverlight (Page 88) MSDN Magazine - February 2009 - Silverlight (Page 89) MSDN Magazine - February 2009 - Silverlight (Page 90) MSDN Magazine - February 2009 - Silverlight (Page 91) MSDN Magazine - February 2009 - Silverlight (Page 92) MSDN Magazine - February 2009 - Silverlight (Page 93) MSDN Magazine - February 2009 - Silverlight (Page 94) MSDN Magazine - February 2009 - Under The Table (Page 95) MSDN Magazine - February 2009 - Under The Table (Page 96) MSDN Magazine - February 2009 - Under The Table (Page 97) MSDN Magazine - February 2009 - Under The Table (Page 98) MSDN Magazine - February 2009 - Under The Table (Page 99) MSDN Magazine - February 2009 - Under The Table (Page 100) MSDN Magazine - February 2009 - Foundations (Page 101) MSDN Magazine - February 2009 - Foundations (Page 102) MSDN Magazine - February 2009 - Foundations (Page 103) MSDN Magazine - February 2009 - Foundations (Page 104) MSDN Magazine - February 2009 - Foundations (Page 105) MSDN Magazine - February 2009 - Foundations (Page 106) MSDN Magazine - February 2009 - Windows With C++ (Page 107) MSDN Magazine - February 2009 - Windows With C++ (Page 108) MSDN Magazine - February 2009 - Windows With C++ (Page 109) MSDN Magazine - February 2009 - Windows With C++ (Page 110) MSDN Magazine - February 2009 - .NET Matters (Page 111) MSDN Magazine - February 2009 - .NET Matters (Page 112) MSDN Magazine - February 2009 - .NET Matters (Page 113) MSDN Magazine - February 2009 - .NET Matters (Page 114) MSDN Magazine - February 2009 - Going Places (Page 115) MSDN Magazine - February 2009 - Going Places (Page 116) MSDN Magazine - February 2009 - Going Places (Page 117) MSDN Magazine - February 2009 - Going Places (Page 118) MSDN Magazine - February 2009 - Going Places (Page 119) MSDN Magazine - February 2009 - { End Bracket } (Page 120) MSDN Magazine - February 2009 - { End Bracket } (Page Cover3) MSDN Magazine - February 2009 - { End Bracket } (Page Cover4)
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.