Friday, April 19, 2013

Using Strongly Typed Properties

When my team and I started to port a Web Forms application over to the MVC side of the ASP.NET stack, I specifically set out to solve an issue we continued to run into. We have these fields on the screen that tie back to some property on an underlying "program," usually exposed as some sort of primitive, such as an int, or string. There are many these properties are found in many programs and usually follow some sort of business rules. Let's say one of these properties is called a Foo. In the Web Forms implementation, we would see something such as the following.

public class SomeProgram : Program
{
    public string Foo { get; set; }
}

public class SomeOtherProgram : Program
{
    public string Foo { get; set; }
}

A "Foo" has a very specific meaning in the domain of the application. In implementation described above, it is very easy to accidentally pass the wrong string to a property because you don't get a red squiggly telling you that you just set that "Foo" with a "Bar" because they're both just strings.

Instead, in our rework, we created a base class called CommonType. (These are basically just value types in the domain driven design world, in that we don't care about their individual identity.) From that CommonType, we have created other "types" to represent our data. So, instead of our properties look like they did, above, we now have something else like this:

public class SomeProgram : Program
{
    public Foo Foo { get; set; }
}

public class SomeOtherProgram : Program
{
    public Foo Foo { get; set; }
}

Now we can't accidentally pass in a "Bar" to a "Foo" without some sort of conversion and we get the help of the compiler to tell us we're mapping things incorrectly. The other benefit of doing this is that these fields need to be represented the same way in the UI. Instead of having the same hand-coded (usually inline) styles, we can create editor templates, model binders, and tell MVC how to play nicely with our types.

@model X.Y.Z.Program
@using (Html.BeginForm())
{
    
}

Now we have one, and only one, place that defines what a "Foo" looks like in the application instead of relying on Find-All.

No comments:

Post a Comment