Codesmith and .NetTiers thoughts
Posted by Keith Elder | Posted in .Net, Programming, Smart Clients | Posted on 27-07-2006
I was catching up on some blog reading tonight and saw where Daniel had posted about using Codesmith and .NetTiers to generate code. I’ve been using this for several months myself but hadn’t gotten around to blogging about it.
Quick intro to what it is. Codesmith is a client app that users templates to generate code. .NetTiers is an open source projected that provides templates to generate a n-tiered architecture. If you watched my video cast of building a three tiered architecture in Visual Studio, using these two tools can quickly create the business and datalayer for a project. Obviously it isn’t going to write business objects for you with all of your validation rules, but it does provide a start (if you think business objects are database records, which I don’t fully agree with). On the Codesmith site you’ll find a nice 15 minute tutorial which can explain better how they work together.
The thing I use the most with .NetTiers is validating business entities. Let’s say you have a Contact table in a database. After .NetTiers runs, it will create a business object called “Contact”. This object is generated into two partial class files typically called:
- Contact.cs
- Contact.generated.cs
The generated file shouldn’t be modified, the other you can modify. Typically you will add a new method called “AddValidation()” to the Contact.cs object called from the constructor which adds all of your business rules. For example, FirstName and LastName are required fields. First and Last name much pass a regular expression validation before saving. There is a folder in the businesslayer that .NetTiers generates called Validation where there are several generic objects to assist you with common validation rules. You can also add your own. For example, you could write a method to have the database check to make sure no one else has the first and last name in the database before saving it. The validation rules use delegates so you can write any method or logic you need to do validation. Here’s some sample validation code:
1 Validation.CommonRules.CompareValueRuleArgs<int> schemaValidationArgs = new Validation.CommonRules.CompareValueRuleArgs<int>(“SchemaValidationId”, 0);
2 schemaValidationArgs.Description = “Schema Validation is a required field and must be greater than 0.”;
In the example above the property SchemaValidatoinId must be great than 0. The way the validation in .NetTiers is setup is based on a collection of validation rules. Once your list of rules is established you simply need to invoke the Validate() on the object. Validate then processes all of the rules in the list, making calls out to each delegate as it needs to. What gets created as a result of this is a BrokenRulesList which is a property of your business entity. Since I don’t have a contact table handy to generate actual code, here is some sudo code as to how things fit together.
1 using System;
2
3 /// <summary>
4 /// Summary description for Contact
5 /// </summary>
6 public class Contact : ContactBase
7 {
8 public Contact():base()
9 {
10 AddValidation();
11 }
12
13 private void AddValidation()
14 {
15 Validation.ValidationRuleArgs nameArgs = new ValidationRuleArgs(“FirstName”);
16 nameArgs.Description = “First Name is a required field.”;
17 this.ValidationRules.AddRule(Validation.CommonRules.StringRequired, nameArgs);
18 }
19 }
20
21 public class Test
22 {
23 Test()
24 {
25 Contact contact = new Contact();
26 contact.Validate();
27 if (contact.BrokenRulesList.Length > 0)
28 {
29 // whoops, you have errors
30 }
31 }
32 }
If you are like me and are writing Smart Clients with web services, the BrokenRulesList gives you an easy way to let user’s know what is wrong. As a typical pattern, I pass the BrokenRulesList (which contains brokenRule objects) as an out parameter on the web service. This way I can easily display or handle the errors in the Smart Client so it is friendly to the user.
Since you know the property in the BrokenRule object that is causing the problem, along with the description of the error, a quick foreach loop through your input controls on your windows form and you can automatically set ErrorProviders on your controls (same could apply for asp.net). This could all be automated as well with enough time I think too.
One thing I’ve noticed about some developers using .NetTiers is once they start using it, they want to use it for everything! This is just wrong. If you think of it from the standpoint of being able to put business rules and validation on information before it hits the database, you’ll be ok. It isn’t the swiss army knife of developing apps though.
Here is something else to consider about .NetTiers. What if you only need to display one record with limited data, one or two columns? This is where .NetTiers doesn’t help at all because given a primary key or a search filter it will always load the entire record. To my knowledge there is no way to tell it what to load or not to load into the object. Which logically speaking makes sense because if you updated the information you wouldn’t be able to pass the business rules of the object to save it. It’s a catch 22 really. In this case it is easier to just write your own query. Sometimes you may not care, but in the enterprise where speed counts, you just can’t afford to be lazy.
Nope, dropped it.
I liked your article quite a bit. One thing when I need to show only a few columns from a field, or a few columns joined over several tables, I create a view and have netteirs generate the code for the view. It does not generate any code to save a view though. So if I need to save any information out of a view, I’ll do custom code then, or just load and update the entities for the records then. Not optimal.
I was curious if you were still using it when Linq and Entity Data Framework out.