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…
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.
26 May
Posted by: Matt in: Community
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:
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:
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!
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 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.
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.
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:
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.