March 2006 - Posts
Gregor Hohpe delivered what sounds like an excellent “keynote” to a room full of Java programmers at the Server Side Java Symposium. Within his presentation he talked about how we need to write code with people in mind rather then the computer. We need to make beautiful code.
"Write code that people aren't compelled to mess up," he said. "Make code so the next person sees you put thought into an elegant solution."
"Write code for people not machines," was Hohpe's mantra throughout his keynote. He suggested that if programmers were only writing for machines, they wouldn't need Java, they could revert to working in Assembler.
"Where did all the beautiful code go?" he asked,…"Maybe the janitor comes in during the night and messes up our code?"
Harry Pierson has an interesting post entitled “The Dual Schema Problem” where he talks about the problems that we face in mapping our object model to our relational model. Although todays mappers help reduce the amount of work required to get data out of our relational model and into our object model they don’t help make our lives easier when it comes to managing our schema. We still have to maintain our schema in two places. And we still (for the most part) have to start with our database schema and work our way back to our objects.
In an ideal environment the “schema” of our application would reside in the same place our object model lives. As our object model evolved so to would our schema. We’d work in a single “environment”, we wouldn’t jump between VS.NET and SQL Server, and we’d be more productive.
Andres has an interesting post on DLINQ and ASP.NET Build Providers. As you might be able to tell from my last couple of posts on DLinq I think it’s pretty cool. As some readers pointed out much (if not all) of what I was showing in my posts can be done in today’s mappers. What I like so much about DLinq how nicely integrated it is in the language which is in large part due to the new C# 3.0 language features (by the way when can we have them
)
Anyway back to the point of this post. As DLinq gets closer to release I suspect we’re going to see a lot more people get interested in the idea of O/R Mapping and start to use DLinq. Making the process of building applications using DLinq smooth will be key to it’s success in the .NET world (we can argue if this is a good or bad thing at another time). Having “things” like custom ASP.NET Build providers will certainly help.
Rather then posting a short novel on DLinq I decided to cut my previous post “short” and include some more highlights in this follow up post:
- Take(5) – SELECT TOP 5
- Skip(10) — Skips the first 10 records
- Supports “including” related data to prevent additional roundtrips to the database via .Including(c => c.Orders) syntax
- Supports string functions
- StartsWith => ColumnName LIKE ‘foo%’
- EndsWith => ColumnName LIKE ‘%foo’
- Contains => ColumnName LIKE ‘%foo%’
- Length => LEN(ColumnName) > 30
- Substring => SUBSTRING(ColumnName, 0, 5)
- ToUpper => UPPER(ColumnName)
- ToLower => LOWER(ColumnName)
- Concurrency support – OptimisticConcurrencyException is thrown when two users try to modify the same object.
- Supports for direct SQL:
var products = db.ExecuteQuery<Product>(
"SELECT [Product List].ProductID, [Product List].ProductName " +
"FROM Products AS [Product List] " +
"WHERE [Product List].Discontinued = 0 " +
"ORDER BY [Product List].ProductName;"
);
Rather then posting a short novel on DLinq I decided to cut my previous post “short” and include some more highlights in this follow up post:
- Take(5) – SELECT TOP 5
- Skip(10) — Skips the first 10 records
- Supports “including” related data to prevent additional roundtrips to the database via .Including(c => c.Orders) syntax
- Supports string functions
- StartsWith => ColumnName LIKE ‘foo%’
- EndsWith => ColumnName LIKE ‘%foo’
- Contains => ColumnName LIKE ‘%foo%’
- Length => LEN(ColumnName) > 30
- Substring => SUBSTRING(ColumnName, 0, 5)
- ToUpper => UPPER(ColumnName)
- ToLower => LOWER(ColumnName)
- Concurrency support – OptimisticConcurrencyException is thrown when two users try to modify the same object.
- Supports for direct SQL:
var products = db.ExecuteQuery<Product>(
"SELECT [Product List].ProductID, [Product List].ProductName " +
"FROM Products AS [Product List] " +
"WHERE [Product List].Discontinued = 0 " +
"ORDER BY [Product List].ProductName;"
);
One of the things I didn’t mention in my previous CAB Best Practices post is that while out in Redmond I got a chance to have a small peak at some F# and Linq stuff. While I’ve read a decent amount of information on Linq, DLinq, and XLinq, I hadn’t done much of anything from a coding perspective with these technologies. Since that fateful day in building 20 I’ve started to dig into Linq a bit more. The short story is it’s cool. The longer story is that it’s really cool. 
I’m sure everyone has seen the basic programming api that Linq provides but as a quick review let’s checkout a simple block of C# code to return a list of customers from the Northwind database.
var customers = from c in db.Customers
where c.City == "London"
select c;
This will return a list of customer objects that have “London” as their city. What’s cool about this is that you have a nice strongly typed query API. In addition to all the nice select like querying provided by Linq it also provides a number of other “functions” such as Sum, Min, Max, Average.
var amount = db.Products.Sum(p => p.UnitPrice);
One of the down-sides of a lot of O/R Mappers is that they don’t make things like the above easy. This often times results in developers witting a bunch of extremely inefficient code. As an example the below is some not so efficient code that one might write using a typical .NET O/R Mapper.
decimal amount = 0;
List<Product> products = new Repository<Product>().FindAll();
products.ForEach(delegate(Product product) { amount += product.UnitPrice; });
The query using DLinq results in one small compact database query that returns a single result.
SELECT SUM([t0].[UnitPrice]) AS [value] FROM [Products] AS [t0]
While the second fictionary O/R Mapper code results in a larger query that returns all the product data and relies on the provided C# code to do the work. The other very nice thing about DLinq is that you can return only the data you want by specifying what data to return in your select.
var customerNames = from c in db.Customers
select c.CompanyName;
// SELECT [t0].[CompanyName] FROM [Customers] AS [t0]
Again DLinq results in much less data coming back from the database then a typical O/R Mapper would provide. The other “super cool” feature that is available within Linq is anonymous types. As an example lets assume we want to get a bunch of “Address” objects extracted from the details within our Customers table. Let’s also assume we don’t have a “Address” object in our system.
var addresses = from c in db.Customers
where c.City == "London"
select new { c.Address, c.City, c.Region, c.PostalCode };
/*
exec sp_executesql N'SELECT [t0].[Address], [t0].[City], [t0].[PostalCode], [t0].[Region] FROM [Customers] AS [t0] WHERE [t0].[City] = @p0', N'@p0 nvarchar(6)', @p0 = N'London'
*/
foreach(var address in addresses) {
Console.WriteLine(address.Address);
Console.WriteLine(address.City + " " + address.Region + " " + address.PostalCode);
}
As you can see we select the Address, City, Region, and PostalCode from our Customers table and turn them into an anonymous type representing our Address. Trying to do something similar using C# 2.0 and a typical O/R Mapper would result in much more code. It’s also nice to be able to have groupby, order by, having, and more as natively supported operations.
var q =
from p in db.Products
group p by p.CategoryID into g
select new {
CategoryID = g.Key,
MaxPrice = g.Group.Max(p => p.UnitPrice)
};
/*
SELECT [t1].[CategoryID], [t1].[value] AS [MaxPrice]
FROM (
SELECT MAX([t0].[UnitPrice]) AS [value], [t0].[CategoryID]
FROM [Products] AS [t0]
GROUP BY [t0].[CategoryID]
) AS [t1]
*/
foreach(var p in q) {
Console.WriteLine(p.CategoryID);
Console.WriteLine(p.MaxPrice);
}
All in all Linq and more specifically DLinq look to be headed down the right path. As a O/R Mapping junkie I’m interested in seeing where things progress from this point forward. It appears that DLinq is making sure that most of the SQL operations and keywords find their way into the core language which will hopefully mean a lot less O/R Mapping abuse in .NET land.
One of the things I didn’t mention in my previous CAB Best Practices post is that while out in Redmond I got a chance to have a small peak at some F# and Linq stuff. While I’ve read a decent amount of information on Linq, DLinq, and XLinq, I hadn’t done much of anything from a coding perspective with these technologies. Since that fateful day in building 20 I’ve started to dig into Linq a bit more. The short story is it’s cool. The longer story is that it’s really cool. 
I’m sure everyone has seen the basic programming api that Linq provides but as a quick review let’s checkout a simple block of C# code to return a list of customers from the Northwind database.
var customers = from c in db.Customers
where c.City == "London"
select c;
This will return a list of customer objects that have “London” as their city. What’s cool about this is that you have a nice strongly typed query API. In addition to all the nice select like querying provided by Linq it also provides a number of other “functions” such as Sum, Min, Max, Average.
var amount = db.Products.Sum(p => p.UnitPrice);
One of the down-sides of a lot of O/R Mappers is that they don’t make things like the above easy. This often times results in developers witting a bunch of extremely inefficient code. As an example the below is some not so efficient code that one might write using a typical .NET O/R Mapper.
decimal amount = 0;
List<Product> products = new Repository<Product>().FindAll();
products.ForEach(delegate(Product product) { amount += product.UnitPrice; });
The query using DLinq results in one small compact database query that returns a single result.
SELECT SUM([t0].[UnitPrice]) AS [value] FROM [Products] AS [t0]
While the second fictionary O/R Mapper code results in a larger query that returns all the product data and relies on the provided C# code to do the work. The other very nice thing about DLinq is that you can return only the data you want by specifying what data to return in your select.
var customerNames = from c in db.Customers
select c.CompanyName;
// SELECT [t0].[CompanyName] FROM [Customers] AS [t0]
Again DLinq results in much less data coming back from the database then a typical O/R Mapper would provide. The other “super cool” feature that is available within Linq is anonymous types. As an example lets assume we want to get a bunch of “Address” objects extracted from the details within our Customers table. Let’s also assume we don’t have a “Address” object in our system.
var addresses = from c in db.Customers
where c.City == "London"
select new { c.Address, c.City, c.Region, c.PostalCode };
/*
exec sp_executesql N'SELECT [t0].[Address], [t0].[City], [t0].[PostalCode], [t0].[Region] FROM [Customers] AS [t0] WHERE [t0].[City] = @p0', N'@p0 nvarchar(6)', @p0 = N'London'
*/
foreach(var address in addresses) {
Console.WriteLine(address.Address);
Console.WriteLine(address.City + " " + address.Region + " " + address.PostalCode);
}
As you can see we select the Address, City, Region, and PostalCode from our Customers table and turn them into an anonymous type representing our Address. Trying to do something similar using C# 2.0 and a typical O/R Mapper would result in much more code. It’s also nice to be able to have groupby, order by, having, and more as natively supported operations.
var q =
from p in db.Products
group p by p.CategoryID into g
select new {
CategoryID = g.Key,
MaxPrice = g.Group.Max(p => p.UnitPrice)
};
/*
SELECT [t1].[CategoryID], [t1].[value] AS [MaxPrice]
FROM (
SELECT MAX([t0].[UnitPrice]) AS [value], [t0].[CategoryID]
FROM [Products] AS [t0]
GROUP BY [t0].[CategoryID]
) AS [t1]
*/
foreach(var p in q) {
Console.WriteLine(p.CategoryID);
Console.WriteLine(p.MaxPrice);
}
All in all Linq and more specifically DLinq look to be headed down the right path. As a O/R Mapping junkie I’m interested in seeing where things progress from this point forward. It appears that DLinq is making sure that most of the SQL operations and keywords find their way into the core language which will hopefully mean a lot less O/R Mapping abuse in .NET land.
One of the things that I love about the blogosphere is that it allows everyone to make up new definitions for established practices. As a perfect example have a look at John Wood’s “The Inefficiency of Test Driven Development”.
So what does this have to do with Test Driven Development? Effectively, with only a little hint, I'm determining the requirements based on the reaction to the tests. The tests are driving my efforts to meet her requirements. And this is actually a lot like how TDD works.
With all due respect to John this has absolutely and positively nothing to do with test driven development. If your trying to use TDD to gather your requirements its no wonder your not a fan. Test driven development is not a requirements gathering tool. Believe it or not the people who started the whole agile movement recognized what John is talking about. They recognized that the interactions between people was extremely important. They recognized that the business experts should be a core member of the team and that the interactions between the business experts and programmers was of crucial importance. They even put it at the top of their list of things to value:
Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan
How is it that we’ve fallen so far from what agile and test driven development are about? Perhaps its the fact that the name doesn’t really suite. Perhaps people take it literally and assume that test driven development means that you shouldn’t talk with anyone, just let your tests drive all aspects of your development. Instead of having business prioritize and develop stories we should just dive right into the test driven development process and have the test drive everything. Forget having a vision, just start coding and let the requirements show themselves.
Anyway since I don’t think the point of John’s post was to redefine TDD as a requirements gathering tool I think I’ll stop there. Before I sign off though let me remind you that TDD is about design. It’s not about gathering requirements, its not about defining a contract of intended behaviour, its about following a process that forces you to think about the design of your software every step of the way. If you don’t value design don’t do TDD. If you think TDD is a requirements tool don’t use TDD.
This past week I attended the Smart Client Baseline Architecture Toolkit (SC-BAT) workshop out in Redmond. Overall it was a very beneficial week. I learned a lot about CAB best practices and also got to meet some members of the core patterns and practices team as well as some other Microsoft employees whom I had “heard” of.
It was also my first trip out to Redmond so it was fun to see what Microsoft was like…it’s HUGE. Anyway I thought I’d get going with some posts on what I learned and how I’ll apply what I learned. This first post is a simple list of the best practices that I came away with. Hopefully future posts will be more beneficial for those who don’t know much about CAB.
- There should be a 1–1 relationship between a view and it’s presenter. Presenters are seen as an implementation detail of a view so nothing outside of the view should know about the presenters existence. [CreateNew] is your friend when it comes to creating a presenter for your view.
- Since views know about their presenter (and vice versa) any work that needs to be done by the view should be directly delegated to it’s presenter. The presenter should handle all work that the view needs done. The view should just display data and be extremely “light”. The event broker should NOT be use to communicate between a view and it’s presenter.
private void button_Click(object sender, EventArgs e) {
_presenter.DoMyButtonClickStuff();
}
- If views need to “communicate” between each other they should use EventPublication/EventSubscription.
- WorkItem’s sole purpose in life is to be a container. Rather then being anything “Use Case” related treat WorkItem as what it is, a container.
- The logic necessary for adding views, services, and etc. to a WorkItem should live inside a Controller class. Since the controller needs to know about it’s WorkItem the ControlledWorkItem class should become one of your good friends.
- Controllers are used to get things wired up and running, and for adding everything necessary to the container (aka WorkItem).
- If possible your views should implement the ISmartPartProvider interface. This allows the view to determine how it is displayed within your workspace(s).
- Views and Presenters should implement IDisposable so they can be cleaned up properly.
- The Guidance Automation Toolkit is your friend. Learn it, live it, love it!
This evening I came across an interesting post by Brian Marick. The following paragraph was of particular interest.
I'm not sure whether people on the Agile projects of today have it better or worse. On the one hand, ideas like the above are no longer so outr, so it's easier to find yourself in situations where you're allowed to indulge them. On the other hand, people's actions are much more visible, and they tend to be much more dedicated to meeting deadlines—deadlines that are always looming. I'm wondering these days whether I'm disenchanted with one-week iterations. I believe that the really experienced team can envision a better structure and move toward it in small, safe steps that add not much time to most every story. I'm not good enough to do that. I need time floundering around. To get things right, I need to be unafraid of taking markedly more time on a story than is needed to get it done with well-tested code that's not all that far from what I wish it were (but makes the effort to get there one story bigger and so one story less likely to be spent). It's tough to be unafraid when you're never more than four days from a deadline.
source: http://www.testing.com/cgi-bin/blog/2006/03/15#two-formative-experiences
I have the beginning of an opinion on this but its not fully formed so I’m going to let it settle before posting. What do you think?
Since I’m getting on the Subversion bandwagon I figured I should learn how to use it. TortoiseSVN actually makes working with Subversion very easy but I like understanding the underpinnings of things I use so I picked up Pragmatic Version Control Using Subversion.
This afternoon after getting home from lunch at the playground with the kids I picked up my nice new Subversion book to get up to speed. Overall the book is a good one to pick up if your going to start using Subversion. With that said I’m not sure it’s really required. As I already stated Subversion along with TortoiseSVN is very easy to use and doesn’t really consist of that much “meat”.
I did enjoy learning more about how the author recommends organizing things in Subversion as well as how best to manage tagging, braching, and merging source. It was also good to get a solid overview of all the Subversion commands that TortoiseSVN hides behind it’s nice UI.
Overall a good read, especially for those completely unfamiliar with version control and/or Subversion.
As a software developer, as well as a member of a software development team, version control is a critical aspect to the work I do. Over the years I’ve used several different version control providers with varying degrees of success.
The majority of my professional life I’ve worked with Visual SourceSafe (VSS). Although the experience hasn’t been stellar, I’ve actually had a surprisingly low number of issues with VSS…until recently. At home I’ve used VSS, Vault, and Subversion. Since at home it’s just me I don’t have many hard core requirements.
Ok, so back to the recent problems with VSS. Every since we’ve been using .NET 2.0 (which started with early betas) we’ve been having a lot of issues. I should note that some of these issues where specific to the VSS integration within VS.NET.
- Get latest takes a long time, and often hangs
- The pending checkins window takes forever and a day to come up and often hangs VS.NET
- While checking in files VSS bombs out which results in the repository becoming corrupted
- Repeated corruption problems
- Merge changes doesn’t exactly merge (sometimes)
Over the course of the last several months we’ve been talking a lot about moving to some alternative source control providers. Since almost everyone on the team had either had very good experiences with Subversion, or heard of people having very good experiences it came up as the best option in most of our conversations.
We’ve been running on Subversion for a couple weeks now and I’ve been very impressed. The top advantages that we’ve seen are:
- Must faster then VSS
- Checkouts over the VPN used to be impossible but are now very doable
- Our build time within CC.NET has gone down considerably (on the order of 3–4 minutes)
- TortoiseSVN is a nicer interface then VSS (integration with the shell is top notch)
- Atomic commits are a very good thing.
- Easy to setup – we were up and running in the matter of a half day
- Setting up the subversion repository took 3–4 hours since we had to figure out how to install it
- Importing our existing source took about 5–10 minutes
- Updating our continuous integration environment took about an hour. Most of that time was spent perusing the CC.NET help and trying to figure out why autogetsource “wan’t working” with subversion. It turns out that you have to do the initial checkout yourself on the build machine in order for this to work.
Funny side note: while spell checking this post BlogJet wanted to change VSS to ASS 
Often times while I’m pairing I get strange looks for using new C# language features that aren’t common knowledge yet. I’m cool like that. Or not.
Anyway, one of the new operators in C# 2.0 which I hadn’t really used or come across yet was the ?? operator.
The ?? operator returns the left-hand operand if it is not null, or else it returns the right operand.
While the ?? operator was primarily added for Nullable types it can also be used with reference types. So instead of writing one of those lovely ternary operators like so:
TreeNode rootNode = (myNode.Parent !=
null ? myNode.Parent : myNode);
You can instead write:
TreeNode rootNode = myNode.Parent ?? myNode;
Pretty snazzy eh?
One of the things that a few of my co-workers have been discussing recently is the need for a new modifier in C# to identify things that you want to be testable. Tonight I decided to look into re-writing C# to include a “testable” modifier. Ok, not really.
What I was looking into was the InternalsVisibleTo attribute that is available in .NET 2.0. After taking a quick peak at the MSDN page I was able to setup my test assembly as a “friend assembly” by adding the following lines of code to my business libraries AssemblyInfo.cs:
#if
(DEBUG)
[assembly:
InternalsVisibleToAttribute(
"MyBusinessLibrary.Tests")]
#endif
The friend assemblies feature in .NET allows you to access internal members from your friend assembly. All private types and private members will remain inaccessible as you would expect. I’m not sure how much this will help, or if it will help at all, but at the very least I learned something new tonight. 
Nick Bradbury of FeedDemon fame has an interesting post about how he’s been leveraging XSL Transformations to create a flexible GUI. It’s interesting to hear a guy who has created a bunch of very successful windows applications talking about XSL and how it can simplify GUI development within the context of a desktop application.
I still feel like a beginner with XSL, but I grok its power now that I've used it for a while. The ability to create a friendly, web-like user interface by transforming XML documents is definitely handy, and in some ways I find it simpler than "traditional" GUI development since I can make huge design changes with a few lines of XSL without having to re-arrange a dialog full of widgets.
As a “former web guy” I do miss some of the flexibility that the web world offers. While you certainly can’t provide as rich of an interface as you can with WinForms it is easier to move things around, adjust, and modify. It’s also easier to provide “skinning” functionality since you have CSS to handle all the layout, colors, and alignments of your UI.
Is it possible that the sweet spot could be somewhere in between the web and windows worlds?
Right now our planning days suck. They take a long time, they're filled with a ton of back and forth conversations, and a lot of unneeded questions. The good news is that we're getting better at it, the bad news is it still sucks.
In an effort to figure out ways to help us improve our estimating and planning I picked up Mike Cohn's
Agile Estimating and Planning book a couple weeks ago. I've recently started working my way through it and have been reviewing a lot of information on how agile teams estimate stories and plan their iterations.
A couple nights ago I read about Poker Estimation which goes something like this. Every member of the development team gets a series of cards. A total of 5 cards are given out each with a number on it. The numbers are 1, 2, 3, 5, and 8. After business describes the story everyone on the development team picks a card and shows the rest of the team. After reviewing everyone's "number" and evaluating whether or not the team is in agreement the process is continued (if necessary) or the team moves onto the next story. The focus of Poker Estimation is getting everyone on the team to quickly give an estimate. Rather then long drawn out discussions about all the intricit details of a story the team instead focuses on the overall "feel" for the story. Each developer gives the story a relative score by comparing it to other stories that they've either completed or estimated.
I'm not sure if it would help, or work, but it sounds like an interesting approach. I think by switching to Poker Estimation as well focusing on estimating in story points rather then ideal days we might be able to speed up our estimation and planning and make it suck less.
It looks like the new Mac mini is out. It looks nice, and very tempting. I’ve been thinking about the MacBook Pro since I’m a big laptop fan but it’d probably be easier to justify a Mac Mini. If only I could buy a computer without maxing it out I’d be in much better shape. 

vs.

Which would you go with?
I think I’ll wait a while…hopefully.
As many of you who read my blog regularly know by now I’m a fan of the folks over at 37signals, which is why I was excited to checkout their new book, Getting Real.
Getting Real details the business, design, programming, and marketing principles of 37signals. The book is packed with keep-it-simple insights, contrarian points of view, and unconventional approaches to software design. This is not a technical book or a design tutorial, it's a book of ideas.
Just as my wife and I where heading out to lunch with our kids I jumped over to the http://gettingreal.37signals.com/ site and purchased the “book” (its only available as a PDF as of now). After returning from lunch and some errands I put my son down for a nap, unplugged my Powerbook from the wall and sat down on the couch to figure out if my $19 was worth it or not.
The next thing I knew my battery was down to 4% and I was 160 pages into the 177 page book. Needless to say I enjoyed it. There wasn’t anything absolutely revolutionary in it, just a lot of great advice for building great software, exactly what I was after.
Below are some of my favorite quotes from the book.
Scope down. It's better to make half a product than a half-assed product
The less your app is a chore to build, the better it will be. Keep it small and manageable so you can actually enjoy the process.
Instead of freaking out about these constraints, embrace them. Let them guide you. Constraints drive innovation and force focus. Instead of trying to remove them, use them to your advantage.
If you try to please everyone, you won't please anyone
What you really want to do is build half a product that kicks ass.
Innovation is not about saying yes to everything. It's about saying NO to all but the most crucial features.
Don't expect to get it right the first time. Let the app grow and speak to you. Let it morph and evolve.
If programmers got paid to remove code from software instead of writing new code, software would be a whole lot better.
Don't try to find "tricky" ways to get more cash. Earn it.
http://gettingreal.37signals.com/
In my previous post I mentioned that I believe that validation logic should live in the business layer
rather then in the UI. I went as far as to say you should have the rules for validation defined in one place, your business layer, and have your other layers use those rules to apply the validation as necessary. I’ve decided to write a series of posts on how I’ve implemented such a setup in my custom .net framework (I need a cool name for it like “Rails” or something
). In this post I’m going to quickly show how I define validation rules in my business layer and talk through how I then use those rules within the UI. In future posts I’ll dig into more specifics of what the code actually looks like to apply the rules in the UI. Let’s take a look at a sample entity object:
public class Role : EntityObject {
public Role() : base() { }
public Role(int id) : base(id) { }
[Persist, Required, MaxLength(50)]
public string Name {
get { return _name; }
set {
SetDirty(true);
_name = value;
}
}
[Persist, MaxLength(250)]
public string Description {
get { return _description; }
set {
SetDirty(true);
_description = value;
}
}
[Persist, Required]
public int SiteID {
get { return _siteID; }
set {
SetDirty(true);
_siteID = value;
}
}
string _name = String.Empty;
string _description = String.Empty;
int _siteID = -1;
}
As you can see this is a simple Role entity that contains a Name, Descriptions, and SiteId. Within my framework I define many of the rules for how an object should be treated using a set of custom attributes. The [Persist] attribute tells the underlying framework that when .Save() is called on a role instance that particular property should be persisted to the backend data store.
From a validation perspective we can see two custom attributes that define some validation rules for the Role object. The [Required] attribute specifies what properties require a value to be set, and the [MaxLength] attribute defines the maximum length for the name and description property.
Every time a Save() is called on a role object the persistence layer will ensure that a Name, and SiteID is provided and that the lengths of the Name and Description properties are shorter then 50 and 250 characters.
The second piece of the equation is getting the rules defined via these custom attributes applied when people are entering roles into the EditRoles.aspx page. The easiest solution would be to drop a couple RequiredFieldValidator controls on the page as well as set a maximum length on the textboxes that users enter the name and description into. But what happens when my rules change? What happens when I decide that description should also be required, or when I adjust the name field to be 100 characters rather then 50.
If the validation rules where defined in both the business layer and UI layer I’d have more then one place to update my validation rules. Those of you familiar with the DRY principle know that this is far from ideal.
Instead what I’ve done in my framework is applied the validation rules defined on my business object to my UI. One of the wonderful things about ASP.NET is that you can add and remove controls from pages at runtime. What this allows me to do is dynamically inject required field validators into my ASP.NET page at runtime by inspecting the rules defined on my Role entity. This keeps the rules defined in one place and helps me to sleep better at night knowing that nobody is going to get a Role into my system without a name. What a relief! 
Rhocky has an interesting post which poses the question...
Should validation logic be in the UI or in business objects?To get right to the point,
validation logic should be in your business object layer. End of story.
Ok, it's not really the end of story I have more to say on the subject. As Rhocky points out in his post most (if not all) asp.net applications have all validation logic in the UI only. For some trivial applications that might be enough but for most applications that doesn't cut it.
Rather then focusing your attention on getting all the validation logic setup in your GUI you should instead be focusing on how you can define the validation rules in one place and have it applied in several different scenarios. By putting validation rules in one place you can then use those rules to perform validation in your UI, as well as within your business layer. This helps you ensure that you don't end up with any invalid data in your system.
[1] The rules can be applied before your data layer saves your objects to their persistance store and the rules can be retrieved by the UI and used to dynamically build the UI validation necessary.
So I'm guessing at this point I have a lot of people thinking that theoretically I'm on the mark but actually going and implementing something like this is another story. Since the specifics of how something like this could be done is a little beyond the scope of this post I'm going to leave you with this. It can be done, and once the groundwork is laid you will be very pleased that you spent some extra time getting it setup. It's extremely nice to be able to define your business rules in one spot and have them applied when your objects are saved as well as when UI screens are rendered to the user. I've implemented such a framework in the web world while building
ActiveType as well as in the Windows world. To be fair I've just started developing something for WinForms, but I'm confident it's going to work

To conclude...rather the placing validation rules directly in your UI or duplicating them in both your UI and business layer think about how you might be able to define them in one place and have them applied in multiple scenarios. I'll dive into some of the details of how I've done this in the web and WinForms world in future posts. Maybe I'll even include some code *gasp*.
[1] This of course assumes your not letting people access the backend database directly in which case the rules that aren't enforced in your database won't be applied.