25% discount code on June Headspring training

The month of June sees three training courses:

  1. Agile Boot Camp, part 1 (.Net)
  2. Agile Boot Camp, part 2 (Senior .Net)
  3. ASP.NET MVC Boot Camp

Here’s the scoop:  Call 512-459-2260 and ask for Talisha.  Give her the super-secret coupon code “palermo” to register with a 25% discount.

Here is the low-down.  Headspring does software projects for clients.  We execute all of the projects using a combination of Extreme Programming, Scrum, and Lean.  Through these projects, we have learned how the following things fit together to provide an extremely effective and frictionless environment:  Domain-driven design, TDD, releases, iterations, continuous integration, automated builds, automated testing, Inversion of Control (IoC), pair programming, refactoring, automated deployments, design patterns, interface-based programming, and team dynamics.

These courses are our own custom curriculum that has grown from true experience, not the sales material of a platform vendor.  We share how we are so effective at delivering software, one programming at a time.

Use guid.comb in your database if you need guid keys but don’t want to take a big performance hit

COMB Guids have been around since 2002.  In short, WinNT used to use the MAC address of a network card to help generate GUIDs, and they were pseudo-sorted.  Since then, Guid have become more random and not dependent on anything.  Because of this, SQL Server 2000+ incurs a significant performance degradation when you use Guids as primary keys.  The degradation can be up to a factor of 10.  The reason is the random nature of the Guid and the clustered index on the primary key (which seeks to keep them in sequence).

We must remember that a Guid is not a string even thought that’s how we see them.  A Guid is a 16-byte data structure.  An int is a 4-byte data structure, so we can simply think of it as 4 times as large.  The kicker is that integer keys are sorted and incremental.  Guids are random.  A clustered index can keep them in order for you, but every insert incurs the job of finding where in the list to insert the new value.  Integer keys just go at the end of the list.

If you are using Guids (and NHibernate), check out the guid.comb key generator.  Read Jimmy Nilsson’s article on COMB Guids to understand just why they perform better than normal Guids, and then go through the NHibernate documentation to see how you can use them in your mappings.  Ok, I’ll just give you a sample:

<class name="MyClass" table="MyTable" dynamic-update="true">
<id column="Id" type="Guid" name="Id">
<generator class="guid.comb" />
</id>

<property name="Something" type="Int16" not-null="true" />
<property name="SomethingElse" type="Byte" not-null="true" />

</class>

Data Access Menu – panel discussion video now online

http://www.msteched.com/online/view.aspx?tid=fa50fd2a-05f3-41d9-aaa6-110daea9dce2

image

On Wednesday, I participated on a panel that discussed data access options.  We started out with Richard Campbell throwing in Entity Framework.  The panel was full of architect-level folks, and none of us are comfortable using it yet, but we are all keeping an eye on it.  We discussed O/R Mappers (I plugged NHibernate), but we mostly discussed architecture.  We all agreed on keeping data access out of the way and off to the side.  Wrapping tools is always good, and we all agreed that it is bad to couple our core objects to any data access concern.

We all come from the perspective of line-of-business applications.  10-table wonders (small apps) have different constraints, but the larger, longer-lived apps require more.

I enjoyed the talk much more than the Pros and Cons of Stored Procedures, which was heavily focused on SQL Server and is suited for a DBA developer audience, but this panel fully explored the broader options.

The other panelists were:

Kent Alstad

Stephen Forte

Paul Sheriff

Rocky Lhotka

Richard Campbell

The fallacy of the always-valid entity

I use domain-driven design, and one of the core patterns in DDD is the entity.  I won’t go into a description of aggregates or aggregate roots, but the entity is a central pattern when implementing domain-driven design.

I often encounter the desire by some developers to create an entity that guards itself against ever becoming invalid

Let’s consider the following example of a UserProfile class:

public class UserProfile
{
public string Name { get; set; }
public Gender? Gender { get; set; }
public DateTime? JoinedDate { get; set; }
public DateTime? LastLogin { get; set; }
}
User Profile(s) are created initially with a name and a gender.  Because we never want this entity to be invalid, we may write some guard clauses in the setters:
 
private string _name;
private Gender? _gender;
public DateTime? JoinedDate { get; set; }
public DateTime? LastLogin { get; set; }

public string Name
{
get { return _name; }
set
{
if (string.IsNullOrEmpty(value))
{
throw new Exception("Name is required");
}
_name = value;
}
}

public Gender? Gender
{
get { return _gender; }
set
{
if (_gender == null)
{
throw new Exception("Gender is required");
}
_gender = value;
}
}


This will ensure that the properties cannot be set to null at any time.  In fact, some UI frameworks will catch these exceptions and take the message and turn it into an user’s error message.  Required property validation and the accompanying error messages are misplaced here inside the entity.

  • The fact that name is required needs to be context-bound.  When is it invalid?
  • The message should be the responsibility of the presentation layer. 

These are simple things and don’t illustrate my point very strongly.  In real systems, there is complex logic that decides when an entity is valid for particular operations.  There is seldom only one context for being valid or invalid.  For instance, when loading historical data, some genders may be missing.  Should the application blow up when loading data?  What page would get the error message?  When loading historical data, perhaps the user needs to enter a gender when he edits his profile the next time.  The answer is certainly not to fail the query operation.

The dates in the UserProfile class present the opportunity for some more complex business rules.  For instance, should the JoinedDate ever be greater than the LastLogin date?  Probably not.  If this rule is applied, which setter should contain the validation?  Neither.  Even with this simple validation rule, the always-valid entity notion already falls down.

This type of scenario runs rampant in any non-trivial business application.  This type of validation makes up much of the business logic used to consume and validate user input into the system.  This business logic needs to be separated out into other classes.  Let’s consider what it might look like to factor this out.

public interface IValidator<T>
{
ValidationResult Validation(T obj);
}

public class ValidationResult
{
List<string> _errorCodes = new List<string>();
public void AddError(string errorCode)
{
_errorCodes.Add(errorCode);
}

public string[] GetErrors()
{
return _errorCodes.ToArray();
}

public bool IsValid()
{
return _errorCodes.Count > 0;
}
}

First we’ve defined an interface to represent the concept of a validator.  It returns a result that contains zero or more error codes.  It’s the job of the UI to print the message that goes with the particular error.  Below are two rules that implement this interface.

public class NameRequiredRule : IValidator<UserProfile>
{
public ValidationResult Validation(UserProfile obj)
{
var validation = new ValidationResult();
if(string.IsNullOrEmpty(obj.Name))
{
validation.AddError("NAME_REQUIRED");
}

return validation;
}
}

public class LastLoginAfterJoinedDateRule : IValidator<UserProfile>
{
public ValidationResult Validation(UserProfile obj)
{
var validation = new ValidationResult();
if (obj.JoinedDate.GetValueOrDefault() > obj.LastLogin.GetValueOrDefault())
{
validation.AddError("JOINED_DATE_AFTER_LAST_LOGIN");
}

return validation;
}
}

These two rules encapsulate the logic, and further refactoring could have them apply to multiple types with similar rules.  This topic can become quite large, but the lesson to take home is that these business rules (validation rules) should be external to the entity.  Some of the logic might become methods on the entity, with a boolean return type, but in a medium to large application, there will be so many business rules that factoring them into independent classes becomes a maintainability necessity.

It is futile to attempt to keep entities always-valid.  Let bad things happen to them, and then validate.

Party with Palermo: Tech Ed 2009 Edition (final update)

It’s that time again!
This is the final update before Party with Palermo – Tech Ed 2009 edition.  Pass this along to your friends who aren’t subscribed to the "Party with Palermo" newsletter.

May 10, 2009 – Los Angeles, CA – 7:00PM – 10:00PM

The Westin Bonaventure Hotel And Suites 
404 South Figueroa Street, Los Angeles, CA
Ph: (213) 624-1000
Hollywood Ballroom (3rd floor).

There will be two lines
– Fast track: for those

RSVPed on the website
– Slow track: for those NOT RSVPed on the website

Dropping a business card enters you in the drawing for some cool prizes.

DJ Craig will be providing music and lighting services so feel free to bring your dancing shoes.  Drink tickets and appetizers will be on hand (appetizers normally run out very quickly).  After you use your drink ticket, other beverages are available at the cash bars.

Feel free to take the party to the Westin lobby after 10:00PM!

TWITTER:  The hashtag is #partywithpalermo.
BLOGGERS:  Feel free to add this blog badge to your blog and link back to http://partywithpalermo.com

Bring your Tech Ed neck wallet.  I will have name tag inserts so that everyone at Tech Ed will know that you were at Party with Palermo!

Sponsors

Headspring Systems:

http://headspringsystems.com
JetBrains: http://www.jetbrains.com/
PreEmptive Solutions: http://www.preemptive.com/
TechSmith: http://www.techsmith.com/
Telerik: http://www.telerik.com/
DevMavens: http://www.devmavens.com/
DiscountAsp.Net http://www.discountasp.net/
Infragistics: http://www.infragistics.com/
It’s not too late to sponsor!  Email sponsorships@partywithpalermo.com after you have selected a package.

Save 15%
Whether it’s agile, extreme programming practices, Service Oriented Architecture (SOA), or ASP.NET MVC training you are looking for, Headspring Systems provides training for each for each.  Use this coupon to claim your 15% discount to any of our Boot Camp classes.  These are not for the faint of heart.  The up-coming schedule is as follows:
Agile Boot Camp, Part 1 6/10 to 6/12
ASP.NET MVC Boot Camp 6/17 to 6/19
Agile Boot Camp, Part 2 6/24 to 6/26
Advanced Distributed Systems Design (Udi Dahan) 7/6 to 7/10
Go to http://www.headspringsystems.com/services/agile-training/ for details.

Offer Expires: May 30, 2009

Stored Procedure Panel at TechEd 2009

Paulette Suddarth has published an announcement to a Tech Ed panel I am participating in next Monday at Tech Ed.

“The dispute about the usage of stored procedures almost seems to be a religious one. Both sides have some strong arguments. Who better to debate the topic than four MVPs, two Microsoft product managers and another industry expert who all live and breath the issues from their own frame of references!

During this panel (PAN67) at Tech Ed North America, the team of experts discuss what they believe are pros and cons of each approach and try to decide when to use each of them. If you’re attending Tech Ed, stop by on Monday, May 11, 09:00 – 10:00 in 501C to get the complete story!”

I don’t want to start the debate early, but there are some cases in which you have to use a stored procedure. 

Go to Paulette’s post for the lineup, and don’t forget to RSVP for Party with Palermo.

Testability and TDD are not reasons to use the ASP.NET MVC Framework

Even though Microsoft continues to tout testability as a reason to adopt ASP.NET MVC over WebForms, it really isn’t a good reason.  It is interesting that this is the first product I’ve seen where there is a first-class tutorial explaining how to test code that is coupled to some part of the framework.  Interesting, I’m unable to find a Microsoft tutorial or MSDN Library article talking about unit testing with WebForms, WCF, ASMX, Workflow Foundation, BizTalk, WinForms, WPF, etc.  Now, I’m sure there is some material, and if there is “official” documentation regarding this, I would love to know so I can help bring visibility to it.

I am a big proponent of Test-driven development, and I even teach it in the Agile Boot Camp classes from Headspring.  If you work for me, you must do TDD.  No exceptions.  You might find it odd that I say that testability is not a reason to use ASP.NET MVC.

There is ONE reason I use ASP.NET MVC.  There is ONE reason all of my employees use ASP.NET MVC.  There is ONE reason it is now part of the standard Headspring Architecture for all client web application.  What is this one reason, you ask?

It works the way I want to work, and it doesn’t get in my way.

I realize this reason is very subjective.  I’m ok with that.  My mission is not to convince the whole world to use this framework.  In fact, Headspring is responsible for a handful of open–source projects, but it really isn’t important to us that anyone else uses them.  They are useful to us.  ASP.NET MVC is useful to us.

It works the way I want to work

  • I want work work among .Net interfaces.  When I want to extend something, I like being able to create an alternate implementation for the interface.  This is the way object-oriented programming works.  The simple fundamentals hold fast. 
  • I want to work with small classes.  In WebForms, it was very difficult to keep each WebForm small.  With ASP.NET MVC, it is easy to accomplish.  Each controller action has 3 or 4 lines of code coordinating work with other dependencies.  Route configurations are easily pulled into supporting classes and wired in as an HttpModule.  Views are easily partitioned using partials.  Cross-cutting functionality is easily segmented as ActionFilters.  Rich parameter types are available through custom model binding classes that convert Querystring and Form values into domain objects.  The framework is spread out.  Simple classes everywhere.  Rendering is firmly separated from handling user input.  Business rule validation is easily kept out of the controllers and views in lower layers of the application.  In short, I never find myself trying to find just the right place to wedge in a couple of lines of code.  There are plenty of abstractions.  Every bit of code has a place.
  • I want to distribute work among several members of a team.  It is almost impossible to have more than one person working on a single WebForm.  It is rather easy, however, to have several developers working on the same controller, each have one action.

It doesn’t get in my way

  • It doesn’t saddle me with static properties and other object oriented dead ends.  Every abstraction can be substituted when the default is unsuitable. 

Back to testability

Because ASP.NET MVC is designed well, it is testable.  It was not designed _to be testable_.  It was designed to allow corresponding code to be loosely coupled.  It was designed using solid object-oriented concepts.  Any code designed in this fashion is testable.  Testability is a side effect of good design, not the design itself.

Although I love TDD, please don’t adopt ASP.NET MVC because someone has told you that it will enable test-driven development.  You can do test-driven development without ASP.NET MVC.  Adopt ASP.NET MVC based on other factors.  Adopt it if it works the way you do.  Adopt it if it doesn’t get in your way as much as alternatives.  Adopt it if it helps you move faster.  Adopt it for reasons you value. 

If you are productive with WebForms; if you don’t have any pain with your current approach, please don’t switch.