mhinze.com

Matt Hinze, learning in public

Jeffrey and Eric will be delivering a free afternoon of ASP.NET MVC in Austin on Tuesday, June 16th.  If you haven't yet had a run-in with the new framework or if you're ready to see what we've learned using ASP.NET MVC in the field, this afternoon will be an excellent opportunity to compress learning and maximize your time… 

Simple Nested Closure

Nested closure is one of those fancy patterns Martin Fowler first coined (as far as I know) and published on his DSL WIP site. His formal definition:

Express statement sub-elements of a function call by putting them into a closure in an argument.

You pass a delegate as a method parameter. The receiving method executes the function represented by that delegate against an object it controls.  Nested closure in C# is easy to spot because the delegate is usually typed as Action<T>, where T is the type of the object that the called method will provide as a parameter to our argument function.

The most obvious example is a common extension method:

public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
    foreach (T item in items)
    {
        action(item);
    }
}

Nested closure is like template method, but instead of deriving from a base class to affect behavior, the additional behavior is provided as an argument.  In the same way that template method is great when you want to communicate behavior from derivations to base classes, nested closure works when you want to communicate behavior as you call a method.

Consider working with a common series of steps when writing repository methods against NHibernate:

public Order[] GetAllOpenOrders(Customer customer)
{
    ISession session = GetSession();
    IQuery query = session.CreateQuery("from Order o where o.Resolution is null and o.Customer = ?");
    query.SetEntity(0, customer);
    var results = query.List<Order>().ToArray();
    return results;
}

Code like this – where you have the same basic structure in several methods – can be made more terse by using a nested closure.

public Order[] GetShippedOrders(Customer customer)
{
    const string hql = "select distinct s.Order from Shipment s where s.Order.Customer = ?";

    return Hql(hql, x => x.SetEntity(0, customer));
}

The second parameter is an Action<IQuery>.

protected T[] Hql(string query, Action<IQuery> additionalWork)
{
    IQuery iquery = GetSession().CreateQuery(query);

    if (additionalWork != null)
        additionalWork(iquery);

    return iquery.List<T>().ToArray();
}

Nested closures are also good for adding fluency to APIs.  This is the context of Fowler's writing, and you can see it clearly in Rhino Mocks:

repository.AssertWasCalled(x => x.Save(null), o =>
    {
        o.IgnoreArguments();
        o.Constraints(Property.AllPropertiesMatch(visitToSave));
    });

In this scenario we're passing a delegate that, when invoked later, helps Rhino Mocks configure options for its expectations.

I'm into the idea of a code camp.  So many conferences and presentations I attend are chatty and abstract, it'll be good to see Studio and Resharper and keyboard shortcuts and macros and hard core programming fly around on projectors all day. Since I'm facilitating for six hours, this is a list of sessions that I'm distraught to miss at Austin Code Camp:

  • 9:00 AM Git for people by Joe Ocampo
    I just want to see someone fly through using this so I can upgrade my understanding from novice to .. post-novice. Hopefully some msysgit tricks for the Windows crowd. Can someone record this?
  • 10:00 AM Eric Hexter's talk on Project Automation – Learn about Build and Deployment Automation
    Eric is a master on the subject and I'd love to glean some tidbits from his repertoire.
  • 11:00 AM A Handful of Things You Can Do In Ruby That Scares the Pants Off of C# Developers by Scott Bellware
    I'm at least wary of dynamic languages (in the large), and I'm sure Scott will challenge my (mis)understandings.  Also hoping for a recording.
  • 12:45 PM Enterprise Architecture Patterns: Presentation, Business Logic, and Persistence by Chad Myers and John Teague
    I will make it to this session, at least in part.. I know enough to know that there's so much I don't know.  This one will be all about information literacy.
  • 2:45 PM Test Driven JavaScript by John Teague
    I hope John shows me a better way.. because mine is not frictionless.

Austin Code Camp

I'll facilitate two sessions at Austin Code Camp on May 30th.

The first is called Take It For A Test Drive – clearly a failed attempt at a witty name for a hands-on-keyboard workshop where participants will design and implement a new feature for CodeCampServer, an open source ASP.NET MVC project.  We'll get our hands on NHibernate, TDD, Rhino Mocks, Resharper.. and maybe some ASP.NET MVC (although I'm hoping that we touch the UI as little as possible since that stuff tends to slow workshops like this).

Here's the abstract:

Conception, design, tasking, testing, construction. We'll do it all by building a new feature into a .NET open source enterprise software application. We'll design as a team, test-drive the implementation, and use the tools that enable us to move fast. This is a hands-on, no holds barred opportunity to get down and dirty with TDD. Bring your laptop with required software installed: Visual Studio .NET 2008, TestDriven.NET, TortoiseSVN, Resharper 4.5, SQL Server 2005 Express with mixed mode authentication

It's really important that participants bring their laptops with all the software installed.  If you can build Code Camp Server locally and load the solution in Visual Studio, you're golden.  This isn't a presentation, it's a workshop.

So here's how it will go down:

  • A 15-20 minute warm-up that involves checking out the source code and building it locally.
  • I'll do a quick (very quick) rundown of the project and demo some Resharper stuff.
  • I'll do another very quick intro to TDD if necessary.
  • Then I'll present the specifications for the new feature and the participants will hash out the requirements with me as I role-play a product owner.
  • As a team we'll use pseudo-UML and sequence diagrams to figure out exactly what we'll be doing and we'll task it out step by step.
  • Then we'll go heads down and implement the feature.  I'll speak up and code on a projector at reasonable intervals.

It's a commitment to attend this one – you'll dedicate most of the morning to a workshop.  But if you are where I was a couple years ago – familiar with C# and most of the tools but needing help getting started with TDD and other techniques, I think you'll like this session.

In the afternoon I'll present my Practical IOC talk.  This one is a presentation.

Here's the abstract:

From the basics to interesting, more advanced usage scenarios, we'll discover how inversion of control can give life to object oriented principles and enable higher quality and faster delivery.

I'd say it's intermediate level subject matter.  I have modified it a little since I presented it last.  This one is a few (awesome!) slides and then me coding through usage scenarios.

Hope to see you there!

Welcome Eric Anderson

Today at Headspring we're pleased to have Eric Anderson on board.  Eric's been hanging around the Austin agile software development community for a few years, and he's been to many of the ALT.NET conferences, including the last one in Seattle.  It's exciting to see the company grow in the right direction… welcome Eric!

SubControllers and ViewModel

SubControllers solved a big problem for us when we first started our current project.  I posted about them back in the day.

The problem was isolating authorization to view sections of a page.  In other words, if you didn't have permission X, you couldn't see the top-left section of the screen.  If you didn't have permission Y, you couldn't see top-right section of the screen.  By composing the controllers that decided how to display the sections, we could test drive nicely each controller's authorization check and subsequent decision.

Later we embraced the ViewModel concept and are working with strongly-typed views.  We found that using SubControllers wasn't the best approach in that situation, for a couple reasons:

First, that the view properly invokes the SubController remains untested.  The responsibility for performing the interaction still rests with the view.  So why not just make the authorization check in the view? 

That's the other problem: scattered partial views can be a small maintenance headache.  In our current project, after embracing the ViewModel, there just wasn't a pain that SubControllers cured.

We didn't abandon SubControllers because they didn't work, or because there was a flaw in the implementation, or because they were too complex, or anything like that.  They may still be the right approach for a given screen.

If you're unsure how to share view pieces in your application, refer to Jimmy's excellent guide.

More On Value Objects

A few days ago Dylan Beattie wrote a nice post about value objects.  He explains the idea in a more palatable way than my attempt:

If it’s not clear how to model a particular element in your model, try asking “which one?” If the question makes sense within your own scenario then you’re probably dealing with entities. If the question “which one” is meaningless in the context of your domain then you’re probably better off modeling the subject of the question as a value object.

I suggest that if you're maintaining a collection, you implicitly care which one.

Practical IOC slides and code

Last night I presented a talk titled Practical Inversion Of Control to a packed house at the Austin .NET User Group.  It was a blast.  I'd guess there were 80 developers there, maybe more.  Interestingly, when I asked the room "Who uses an IOC tool at work," about 10 hands went up, at the most.

I tried to focus on the practices of using IOC tools, because there's a lot of abstract jibber-jabber about principles.  Don't get me wrong, I love the principles and the theory.  I just think talking about the practices creates a more powerful pedagogical vector through which a comprehension of the principles can "sneak" in.

If I do this talk again I'll scrap the open generics tidbit.  I think it's really neat, and that's why I included it.  But if one hasn't run into that pain, solving it isn't so cool, and it adds unnecessary complexity to the demonstration.  I'll have to come up with something better to replace it.

Here's an archive of the slides, notes and demo code.

And here's a thing, if you just want to browse a slightly mangled view of the slides:

Presenting at ADNUG

I'm presenting a talk titled Practical Inversion of Control at the Austin .Net User Group on Monday.  This will be a beginner to intermediate level session in which we'll answer the "what", "why" and "how" questions about IOC and explore both basic and more interesting usage scenarios …

Adding to a Value Object property always adds to it, never adds another instance to it.  Distinguishing Value Objects by maintaining a collection of them implies identity.

It is a mistake to attempt to maintain a collection of Value Objects.

Let's take the near-canonical Address, a perfectly valid Value Object as described on page 98 of the Big Blue Bible:

public class Address : ValueObject<Address>
{
    public virtual string StreetAddress1 { get; set; }
    public virtual string StreetAddress2 { get; set; }
    public virtual string City { get; set; }
    public virtual State State { get; set; }
    public virtual string ZipCode { get; set; }
    public virtual Country Country { get; set; }
}

And a perfectly valid usage of this Address Value Object is as a component of an Entity:

public class Customer : Entity
{
    public Address WorkAddress { get; set; }
    public Address HomeAddress { get; set; }
    // ...
}

This, on the other hand, is incorrect:

public class Customer : Entity{
    private readonly ISet<Address> _addresses = new HashedSet<Address>();

    public Address[] GetAddresses()
    {
        return _addresses.ToArray();
    }
}

Again, distinguishing addresses by maintaining a collection of them implies identity. If you tried to edit one of the addresses respecting some immutable Value Object oriented thinking, you would clear the collection, find (somehow) the one you intended to edit, replace it along with all the others.  This is not possible.  When you only care about the values of an object, rather than a key, you cannot find the original one you intend to edit from an instance of an edited object.  If you care about a key you have an Entity.

The original and the edited will never match. You might try to give the Value Object a database key so that it is easy to find.  But if you do that, why again are you clearing all the rest and re-adding them?  That doesn't make sense – just edit it.

There's another problem.  In the "wallet" example you have paper money in your wallet, several pieces of paper.  Your wallet is the Entity and the money is a Value Object.  If you were to take some money out of your wallet, you would subtract from the Value Object, not remove an instance of the Value Object from a collection.  You don't care if you have five ones or one five, you just care that you have five.  Value Objects never collect, they only aggregate.

If you care about each individual instance, you have an Entity.

The best way to model something like this is to use an Entity that has a Value Object component.  If I am maintaining a collection of Addresses, I do actually care that each is different – the trick is to find out why.  In my case I care because the Customer has an address history and I wish to maintain that history.  I model that like this:

public class HistoricalAddress : Entity
{
    public Address Address { get; set; }
    public DateTime? Start { get; set; }
    public DateTime? End { get; set; }
    public AddressType Type { get; set; }
}

Now the HistoricalAddress Entity lives in the Customer Aggregate…

public class Customer : Entity
{
    private readonly ISet<HistoricalAddress> _addresses = new HashedSet<HistoricalAddress>();

    public HistoricalAddress[] GetAddresses()
    {
        return _addresses.ToArray();
    }

    public HistoricalAddress GetAddress(Guid historicalAddressId)
    {
        return _addresses.SingleOrDefault(x => x.Id == historicalAddressId);
    }

    //...
}

… and I am free to edit, list, and delete them with ease.

The one caveat is when you are maintaining a collection of Value Objects that represent all possible values.  If you have a State Value Object you may want to represent a collection of all 50 U.S. States as a select list in the user interface.  This works fine and is programmatically possible, until you are interested in maintaining this collection.