Skip to content

Custom Action method overloading in MVC3

In one of the MVC3 apps i’ve been working on we decided to make sure that all of the urls specify information in a restful fashion, that is they are all directly in the path(route), nothing in request parameters.  Everything was going smoothly until we hit our first action where parameters are optional.

Lets look at this theoretical route table:

"{controller}/{action}/{year}/team/{teamId}/car/{carId}/track/{trackId}"
"{controller}/{action}/{year}/track/{trackId}/car/{carId}"
"{controller}/{action}/{year}/car/{carId}"

So you could imagine that we would have different urls that apply to these routes like:

http://www.racingstats.com/yearlySummary/Nascar/2011/team/AmsOil/car/12
http://www.racingstats.com/yearlySummary/Nascar/2011/track/taladega/car/12
http://www.racingstats.com/yearlySummary/Nascar/2011/car/12

The problem is that this url pattern isn’t gracefully handled out of the box with mvc3.  If you tried to hit one you would be greated with a nice exception:

The current request for action ‘Nascar’ on controller type ‘YearlySummaryController’ is ambiguous between the following action methods:….

The reason is that we are specifying the same controller in all 3 (yearlySummary) and the same action (Nascar) in all 3, but with a different set of parameters for all.  The only way you can handle it is to have a single action called “Nascar” that takes every single parameter possible. 

public ActionResult Nascar(int? year, string teamId, int? carId, string trackId)

So based on whatever combination of values either have or do not have a value you will need to determine what behaviour to execute.  You can see that as the number of parameters grows this gets more and more cumbersome and complex.  The worst part of all is that you are using your action to do routing, after you have already gone to the trouble of building a route table! 

We need to do this because the MVC3 routing system does not discern actions based on their parameters, it only differentiates them by name, or by a couple of extended attributes you can apply.

The good news is that they provided a couple of abstract classes you can extend to let you apply filters on action methods as you see fit so you can have the framework pick the appropriate action method however you like.  I’m going to focus on the System.Web.Mvc.ActionMethodSelectorAttribute abstract class.  This class implements only one abstract method.

public abstract bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo);

So when you implement this method in your custom Action Method Selector you get to work with the current controllerContext which includes information like the current request, route value parameters, etc.  You also get the MethodInfo instance for the method that the selector is currently being applied to.

Lets say for the example above, instead of having a single action method that takes in all parameters we want to have a separate action method for each combination of parameters we are passing in.

public ActionResult Nascar(int? year, string teamId, int? carId, string trackId)
public ActionResult Nascar(int? year, string trackId, int? carId)
public ActionResult Nascar(int? year, int? carId)

So we can differentiate them by parameter names as they all have a unique combination.  Using the abstract class specified above we have access to all the information required to do this.

Through the methodInfo parameter we can get access to all of the parameter names of the current method:

methodInfo.GetParameters()

And through the controllerContext parameter we can get access to all of the route values that were gathered from the request path:

controllerContext.RouteData.Values

The RouteData values are essentially just a dictionary of key/value pairs constituting all of the information from the path.  The one thing you do need to do here is filter out all of the information that you are not interested in.  At the most basic level you need to filter out the “controller”, “action”, and “area” values as those are not used as parameter values for our method.  In some cases the framework also adds other keys with objects such as a “DictionaryValueProvider” which is another thing we are not concerned with.  I handled it by simply ignoring any key that has a value which is not a simple type, and also excluding the 3 keys listed above.

Once you have the route values that you will be passing to a method as parameters, you can just match up the route value keys to the parameter names and only return true if there is a 1:1 match for each value. 

This method has worked well in our project so far.  The obvious limitation here is that you still can’t overload a method with the same number and type of parameters, no amount of MVC magic will help you there.  You could possibly use it in combination with the "[ActionName()]” attribute to use the same action name on a different method but I haven’t tried it.

Enough with the details, i’m sure you all came here for the code Smile

public class MatchParametersOnRouteKeys : ActionMethodSelectorAttribute
    {
        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
        {
            var methodParams = methodInfo.GetParameters();
            List<string> passedValues = GetReleventRouteDataValues(controllerContext.RouteData.Values);

            return CheckIfPassedValuesMatchMethodParameters(passedValues, methodParams);
        }

        public bool CheckIfPassedValuesMatchMethodParameters(List<string> passedValues, ParameterInfo[] methodParams)
        {
            if (methodParams.Length != passedValues.Count)
                return false;

            return methodParams.All(t => passedValues.Contains(t.Name.ToLower()));
        }

        public List<string> GetReleventRouteDataValues(RouteValueDictionary routeVals)
        {
            return routeVals.Where(v => IsNotTheActionOrController(v) && IsASimpleType(v)).Select(rv => rv.Key.ToLower()).ToList();
        }

        private static bool IsASimpleType(KeyValuePair<string, object> v)
        {
            return (v.Value.GetType().IsPrimitive || v.Value is String);
        }

        private static bool IsNotTheActionOrController(KeyValuePair<string, object> v)
        {
            return v.Key != "action" && v.Key != "controller" && v.Key != "area";
        }
    }

So once you add this to your solution you just decorate your action methods like so:

[MatchParametersOnRouteKeys]
public ActionResult Nascar(int? year, string trackId, int? carId)

Happy overloading!

Software Developer and Evolution Conference 2010

Looks like this October i’ll be making my way east out to Winnipeg where I have the opportunity to present two sessions at the Software Developer and Evolution Conference.  I’m very excited as not only will this be my second conference of the year that i’m presenting at, it’s also going to be my first time in Winnipeg.  If you know of any fun family things to check out in Winnipeg please leave a comment!

My first session is about self organizing teams, participating on and leading.  There’s a lot of things to think about when it comes to creating and fostering self organizing teams.  I plan to talk about some of them from the perspective of a manager and leader, as well as a team member on the team.  I’m also coming up with a good exercise that I hope will be fun and help illustrate my points.

The second session will be on iterative development.  I did this session at the Prairie Developer Conference in Regina, and i’ve used the feedback I received from the attendees there to refine the presentation to hopefully be even better, and i’m also incorporating an exercise in to this one as well.

I’ll probably be making more posts on those two topics in the coming weeks, so check back for more.

Self Organizing Teams, a new take on Hiring

People do a lot of talking about self organizing teams in the agile world.  Letting the team figure out how to accomplish a task or solve a problem or just achieve some end in the best way they can determine on their own.  When people talk about this they generally think about what tools the team will use, what language might they pick, will they pair program, will they use test driven development, what actual implementation will they use etc etc.  What happens when they tell you they need more people on the team, or a more diverse skill set and the agreed upon solution is hiring?

Lets assume we work in a traditional company.  The manager for the team figures out what he think the team needs, steals a job description off a job posting site writes up a job description for the position, and passes it on to his boss to ask for approval.  Lets pretend that some magic happens and it just immediately gets approved with some arbitrary salary cap for the position that nobody understands the criteria for.  The job description gets passed off to the HR department, and we wait.  We continue to keep waiting for a while longer.  Then poof, we find out a person is hired that will join our team in 2 weeks, yay!  If you won the lottery, the person is exactly what you were looking for, has all the right skills, fits in with the rest of the team, and is paid fairly according to their skills.  Now go log in to your online banking app and check if you’re a millionaire……….No?  I didn’t think so, because as it happens, most of us have never won the lottery :)

Ok, now lets look at how things might work in an agile organization that has truly self organizing teams with leadership that trusts the ability of those self organizing teams to make good decisions.  In daily standup meetings, it has become a regular occurrence that the team says they are being held up by a lack of some skill set, or just by an insufficient number of people to tackle everything as quickly as desired.  This gets brought to the attention of the manager in charge of the department so a short meeting is held with the team to talk about potential solutions to the problem.  The team and manager discuss different options and eventually all agree that the best course of action is to add another person to the team.  The team tells the manager what things they would like to see in a new person, and the manager uses that information to create a job posting for the position.  The posting is run past the team to make sure nothing was missed and give them an opportunity to suggest changes.  The manager gets the necessary approval (lets just pretend for the sake of this story that the manager’s manager just says “great idea!  go for it!”), and they place a job ad with the job description wherever they choose to do so.

Some time later, a pile of applications for the posting have been delivered to the managers inbox.  This is the point where the really unorthodox sounding parts start to come in if you are from an old fashioned command and control company.  The manager goes to see the team, tells them he has a number of applications for the job posting, and asks the team who would like to review them with him!  A few people from the team want to do this so they figure out the best way to divide up the work and they create their short list of people to interview.

Now it’s time for some phone screens.  We’ll assume that our company has a receptionist who contacted everybody on the short list for us and set up appointments for the calls.  The manager talks to the team and asks if anybody wants to be involved in the phone screen interviews.  The team talks it over and decided that seeing as the phone screen is mainly just a short talk to see if the person sounds like they fit the corporate culture of the company that it wouldn’t be the most productive use of their time, so they opt out of this stage and let the manager handle it, and they will wait until the technical portion to get involved.  The manager is a bit sad because he was hoping he could get out of having to do all the phone screens, but it’s his job to keep the team productive, so time to take one for the team.

Phone screens are done and more candidates are weeded out, the candidates that sounded good get sent a take home coding assignment that was created by the team to use for evaluating their basic skills.  When the coding assignments are received, volunteers from the team review the results and decide which candidates look good enough to meet in person so they can grill them a little harder and see if they will fit in with the team culture, not just the corporate culture. 

Ok, this may sound crazy, but it works!  The manager facilitates setting up an interview in the office with the applicants that have made it to this stage.  Two team members work on a team exercise with the applicant for at least a couple of hours, the longer the better.  During this time the manager is “completely” uninvolved, meaning not present, they should be off doing something else.  When the interview is over the manager discusses how it went with the team members, and ultimately the most important question for the team members to answer is “Would you want this person on your team?”.

So at the end of the day all of the candidates come in and work with a couple members of the team for a few hours, and the team chooses the candidate they would like to add to their team (or rejects them all, lets pretend they picked one).  They help pin down the candidates skill level and value to help the manager determine what this person will be worth to the company (determine the offer that will be made). 

The offer is made, some negotiation inevitably happens, we’ll assume it was successful and the new team member joins the team. 

That was an awful lot of writing compared to the first scenario.  Lots of stuff apparently was happening in that HR department “magic” that happened between handing in the job description and getting the new person I guess!

So when comparing the two scenario’s, lets look at some of the benefits of the second:

  1. the team gets to decide who does or does not join their team
  2. the team evaluates the new team members skills and knowledge
  3. any lieing or “padding” done on the resume or CV will quickly be uncovered by the team, nobody smells BS better than your peers!
  4. you don’t have to rely on winning the lottery!

Questions or comments are welcome, I would love to hear how some other people handle hiring.  The process above is how it’s handled in my department and it has worked out fabulously so far, we’ve never had a single new hire not make it through probation using this process.

Agile 2010 Session Roundup

So far my experience at Agile 2010 in Orlando has been great.  Great location, great conference center, great people, and great information.  It’s been a very busy and exhausting week so far, although i’m sad to think that i’ll be flying out around this time tomorrow and it’s all coming to an end. 

My first session monday morning was titled “The Incentives Trap”.  It was a session exploring what motivates people, primarily focusing on intrinsic vs extrinsic motivators with some exercises to prove out how the different types of motivators affect the work ethic and productivity of teams.  I was on the “square” team which was divided in to developers and testers.  My role on the team was a tester.  I got paid $1 for testing a story and $1 for finding a bug.  The developers got $1 for developing a story and $2 for fixing a bug.  Only the project manager got paid for delivering value.  Can you see who got screwed over in this scenario?  Lets just say the project manager probably didn’t eat that night.  It turns out that generally the team which is allowed to self organize, and is working for a charity for “NO PAY” is the most productive team that delivers the most value.  Why?  Because they are passionate about what they are working for, they are working for a charity because they believe in the cause and want to make a difference.  That’s why it’s important for your development teams to understand and believe in the work they’re doing, it’s the only way for them to be intrinsically motivated to be productive.

This is lining up to be a long post, since that was only the first session I attended, and i’ve attended 2 – 5 per day…. 

My next session was titled “Beyond Scope, Schedule, and Cost: Optimizing Value”.  It was a reasonably good session in which I primarily just came back with some interesting statistics and a couple of ideas.

  • doubling the number of people working on a project typically quadruples the number of defects.
  • 65% of features do not deliver their expected/planned value
  • what is a more successful project?
    • estimated to get 5 value points done in a week and achieved 5.
    • estimated to get 8 points done in a week and got 6

Tuesday morning was the keynote by “Dave Thomas”.  It was a lot of what you would expect to hear at an agile conference keynote.  There were a couple of things that surprised me though, like when he exclaimed “you know we’ve made it now because the tool vendors are here, but let me tell you, if you can’t do it with paper cards, no tool will help you”.  I don’t disagree with him, but the tool vendors are the major sponsors of the conference, so I found it a little ironic that he was denouncing their usefulness to all of the conference attendees.

In the afternoon I got to see a session by Johanna Rothman which I was quite excited about as i’ve been reading her blog for quite some time now.  Her session was titled “Agile Managers: The Essence of Leadership”.  The purpose was to talk about what role managers and leaders play in an agile organization, as many managers often feel lost.  There weren’t really any surprises here for me as we’ve got it fairly well figured out at Point2 (we can definitely improve on execution of it as a management team, but we have our place figured out at least).  The session was a nice indication for me of how well we’re doing, and it was great to see that Johanna is just as good of a speaker as she is a writer on her blog.

Wednesday started out with quite likely my favorite session of the conference so far “Scrum Metrics for Hyperproductive Teams: How they fly like Fighter Aircraft”.  It was given by Jeff Sutherland and Scott Downey, Scott had the title of head agile coach at MySpace and now holds the same title at Napster which I thought was pretty cool.  They had a lot of good information which I couldn’t possible discuss in it’s entirety in one paragraph, so i’ll just stick to a couple of points that stuck out for me which we’ll need to try.  The first is we need a “keystone” story, probably estimated at 3 points, which because the reference point for all estimation done by the team for the rest of eternity.  Why do we need this?  Because as the team gets better they will naturally migrate their estimates along with their increased productivity which makes it hard to track improvements over time.  It also makes it hard to have consistent estimates across sprints when you don’t have a never moving reference point to estimate against.  Another thing I want to try focusing on is getting as many people as possible working on getting the top priority store from in progress to done.  We typically have a pair sign up and work on a story until it’s complete.  If 3 pairs can all work on the same story to get it done faster, we should do that.  A sprint that ends with the top half of the stories finished is better than a sprint that ends with all of the stories 75% done.  The other big area that I want to try some changes is in the team standup meetings.  For now i’ll just say that the scrum masters are doing do much of the driving at the meetings.  Their role in the standup should essentially end with making sure everybody on the team has shown up.  More about that when I get back :)

I had another great session on Wednesday morning called “Coaching Agile Teams: Using Silent Work Techniques to Get to Astonishing Results”.  It was a very interactive session with a lot of activities.  I learned a number of techniques in this session on how to get a greater quantity of ideas out of brainstorming sessions about projects/products, as well as some ways to get much more innovative ideas.  Jesse and I are planning to run at least 2 workshops once we’re back based on the exercises I learned in this session.  I think it’s going to be very valuable for having the entire team feeling more involved in providing ideas that can help shape our roadmap and product decisions.  Jesse and I are both really excited about it.

In the afternoon I went to a couple sessions that didn’t produce too much worth writing about with one notable quote “There’s a big difference between half-assed and half done” referring to people’s natural tendency to prefer delivering something half done with a high level of detail over delivering something finished to a lower level of detail.

Today, thursday, is a bit slower.  It’s the last day of real sessions so everybody is starting to look burnt out (everybody at the conference including presenters).  I went to a session about Design Complexity this morning that was quite interesting.  I had a short debate with the speaker about building what you need instead of what you think you need, as she was advocating spending effort up front designing your implementation to be extensible in the way you think it will need to be extended at the time.  We agreed that if you know it’s going to be extended immediately after this isn’t necessarily bad to do, but we disagreed on if you only “think” it will be extended in that way, but had no plans to do so.

I later went to a session titled “Confessions of a Flow Junky” focused on helping create an environment where people can get in their “flow” to become really productive.  The speaker asked how many people have tried pairing and astonishingly half the room raised their hand, the speaker was pretty impressed.  Then he asked how many do it regularly, and only about half a dozen people put up their hand.  When he asked who know how pairing helps flow, I was the only person in the room with my hand up, so he asked how.  I told him “you feel obligated to the person beside you not to screw around” which had the desired result of everybody laughing, and the presenter agreeing, saying it’s one of the littlest known benefits of pairing.  I enjoyed the session, in particular because after the previous comment I had made, people were asking me questions at the end of the session about how we do things at Point2 and how I thought they could make improvements to what they do.

Networking at the conference so far has been great.  I’ve met a lot of cool people from all over the world.  I’ve met a few people from Ireland, a guy from Finland, a couple from France,  many from the US of course, and a surprising number of Canadians.  I actually happened to run in to a girl that I went to school with at Kelsey in Saskatoon that I haven’t seen since we graduated in 2000!  What are the odds?  I also happened to run in to one of the presenters that I met at PrairieDevCon in Regina this year and it sounds like I might get an opportunity to present at a conference in Winnipeg this October so i’m looking forward to finding out more about that. 

I wanted to post some pictures but uploading them over the hotel wireless hasn’t been working so that will have to wait for later. 

Prairie Dev Con 2010

Today was the first official day of the Prairie Dev Con 2010 conference, starting out with an opening welcome message with a nice breakfast spread.  David, Nyik San, and myself arrived the day before at around 6pm so we’d be in time for the social mixer put on by the Regina developer community before hand.  It was reasonably well attended and I met quite a few people and made some great contacts.  It actually has turned out to be pretty nice being at a smaller conference because it’s making it very easy to build relationships with the other people attending.

This morning I started out by attending an Intro to Agile session which was fairly good.  I was interested to see what somebody else’s take on agile was going to be.  It was an overview of processes and how to do scrum etc so it didn’t overlap too much with my presentation which I was happy to see.

Next up was my presentation “Intro to Agile Development Practices”.  It was quite well attended and went very well.  The audience was very engaged and asked a fairly good number of questions.  Apparently I like to talk more when I have an audience than I do to the white board.  My presentation only took 45 minutes when I was practicing it but at the conference I went almost the full 75 minutes!

photo

The notes for my session can be found here.

After being in sessions until 5:30 this afternoon I attended a supper put on for all the presenters of the conference at “The Diplomat” steak house and got to know a few more of the other presenters a little better.  There’s a very good amount of diversity between the speakers, some coming from Guelph, Virginia, and Utah. 

So far the conference has been great and I really hope it gets put on again next year.  The one thing the conference is really lacking is some non-microsoft content.  There are a lot of attendees who would love to sit in on some Python or Ruby sessions, and everybody who i’ve mentioned Scala too immediately says how much they wish there was a session on it.  Hopefully next year we’ll be able to get some more P2ers presenting at the conference and help round out the technology diversity in the sessions.

The Concept of Feature Fidelity

When we’re building software, we often have a desire to deliver something that will blow people away.  It makes sense right?  Why would we want to deliver something that isn’t impressive, doesn’t work all that well, doesn’t look really pretty etc.

Well, it just so happens that there’s a good reason you’d want to do that, because it still delivers value, even in it’s often simple and unrefined form. 

Consider this scenario, a client comes to you and asks you to build them a chair for their office.  They want it to roll around, comfortable, adjustable height, nice arm rests etc, and they want it as quickly as possible because they don’t have a chair at all now.

Using the typical mentality of not delivering anything until you think it will blow people away, you go away and over the course of a month you build a fabulous office chair.  You showed some pictures of it along the way to the client and they were pleased with the design, however they really wished they could have been sitting down at their desk while they looked at your designs…

The concept of fidelity is simply to deliver the simplest thing that provides value as soon as possible, and the move on to refine it.  Using the chair example, the client wants a fancy chair, but the client also currently has NO chair, so obviously just having anything to sit on provides SOME value.  Thinking in this way, the lowest fidelity solution that will deliver some value to the client might look something like this:

milk crate

The client will obviously not be satisfied with a milk crate as the final product but it isn’t the final product, it’s the first iteration of the final solution.  You would tell the client something along the lines of “here’s what we came up with in the first day, turn this upside down and it will allow you to sit at your desk, we’ll be back in a few days with an improved version for you.  A couple days later you return with:

chairYou tell the client that it’s a little more comfortable than the last delivery, and looks better as well.  You will further refine the chair and be back in another week.  After a week you come back in with:

swivel chair The client takes a look at what you’ve delivered, sits in it, the padded chair is comfortable, it looks stylish, and they tell you this is my chair, this is what i want, don’t make any more changes.

So, what are the main differences here?  The client ended up with an end product they were happy with in both cases right?  The second method had a couple key benefits though.  First of all, the client had results in hand and was able to use them (start sitting down) the next day, instead of having to wait for a month.  Also because the team was delivering improvements regularly the client had many opportunities to suggest how they would like things changed.  Finally, the client has the opportunity to stop the development of the product early for any reason and still be left with a usable product!  So whether it turns out that the client is happy with less than they originally asked like in my example, or if the client just ran out of money and had to stop early, they are always left with something usable.

You could make the argument that this is just iterative development, and technically you are correct, however it’s important to remember the fidelity aspect which is that each iteration should provide a usable product that provides value.  Consider another way to iteratively deliver a chair to the customer.  In the first iteration you deliver fully refined wheels, in the second you deliver the adjustable chair post, in the third you deliver nice leather wrapped arm wrests, in the fourth a nice padded leather seat, in the fifth a nice leather chair back, and in the sixth you put it all together.  That’s iterative right?  You produced and delivered a piece of the product in each iteration and showed it to the client.  The problem is that you weren’t delivering any value with each iteration.  The customer doesn’t realize any value until the last iteration when you put it all together, which means if the project had to be stopped early, the client is left with nothing useful.  Even worse, the customer can’t see how everything is going to work together until you put it all together for them, so they don’t have much ability to give feedback on your work.

Always deliver in iterations that provide value to the client, so they are left with something useful that provides value no matter how deep in to the project you are.

Iterative Development – An Introduction

Iterative development is a pretty basic concept.  You just develop iteratively…  Hmm pretty sure i read once that you shouldn’t use the word you’re defining in the definition.  Lets try again.

Iterative development is the practice of developing software in small defined chunks of time.   This is in contrast with the old-school method of starting a project and working on it over the course of months or years in one long chunk, or iteration.

Lets just dig in to the meat of why it’s important.  Imagine you wanted to get a house built.  You line up a contractor who has experience building houses.  You tell him you want a 1200sq ft house with lots of windows and a double garage.  He asks you what layout you want, where should the windows be, do you want a deck, what colors for the interior and exterior etc.  You answer him by saying “I don’t know, I hired you because you’re good at building houses, so you just make sure it’s 1200sq ft and has lots of windows”.  Can you see where this is going?

Six months later he calls you and says the house is done.  You walk in and while the house is impressive, it’s not how you had envisioned it, and with the amount you are paying him, you want it to look how you want.  Unfortunately now that all the work is already done, it will cost a LOT more to make changes.

Software is the same way, if somebody comes and says to you “I want a system that does X” but they don’t have any details as to how it should look or work, it would be foolhardy to believe that they are going to just be happy with whatever you deliver to them.

Iterative development helps with this by allowing you to break up the project in to small iterations, the smaller the better, ideally 1 or 2 weeks.  This way you can show what you have accomplished during each iteration to the customer and see what they think, and get their feedback on what they would like changed.  Even if they customer had no idea what they wanted ahead of time, you can bet that they will after they see what you have built.  The sooner you get that feedback from them, the cheaper it will be to ensure the project turns out how they want.

One of the other big advantages of dividing work up in to short iterations is that it’s a lot easier to estimate what you can get done in 2 weeks than in 2 months.  Once you have the project divided up in those iterations it also becomes a lot easier to see if you’re falling behind or not as well.

That should give you a basic idea of some of the advantage iterative development provides.  I’ll go in to more detail in future posts of some of the other advantages.