Speaking at the Shreveport, LA .Net User Group on June 15th

Here’s the website:  http://www.shreveportdnug.org/

I have now lost count on how many times I’ve given this presentation, but it’s a lot.  The first one was at Tech Ed 2008.  I actually got the title for free when Phil Haack punted it to me when he couldn’t give it.  It’s has received great reviews everywhere I’ve taken it.

Topic: TDD, DI, and SoC with ASP.NET MVC

Summary: Spelled out, it is test-driven development, dependency injection, and separation of concerns with Active Server Pages .Net Model View Controller. This talk will dive into how to design a presentation layer using ASP.NET MVC. In today’s industry, TDD, DI, and SoC are proven concepts that lead to more maintainable applications. Along with demonstrating how to use these techniques with ASP.NET MVC, we will discuss just what concerns should be separated. This talk provides a unique perspective on separation of concerns and uses TDD and DI to make it happen. MvcContrib is used in all the demos.

Location: Centenary College, Wright Math Building Room 103 – map

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