Action (Delegates) with more than four parameters

Mar 1, 2011 at 11:52 AM


We have been using StoryQ for quite some time now, and while it's great we came up into a little problem with one of our test cases.

Some of our methods require more than four parameters and the Action doesn't allow it. So I made a little fork of the original project adding the following lines in the file, a bit below line 120:

/// <summary>
/// <#=prefix#> [<#=target.Label.Name#>].
/// <#=Tooltip(exit)#>.
/// </summary>
/// <remarks>This overload infers its text from the name of the parameter <paramref name="descriptiveAction"/></remarks>
/// <param name="descriptiveAction">
/// A descriptively named method that should be run to fulfil this story fragment. The method's name will be used as the description for this fragment, once converted from CamelCase
/// Any underscores in the method's name will be used as placeholders and will be replaced with the <see cref="object.ToString"/> of each respective argument.
/// Do not use a lambda or anonymous method here, as the name will not be human readable
/// </param>
/// <param name="args">The arguments to be passed to <paramref name="descriptiveAction"/></param>
/// <returns>The next fragment of your story, a <see cref="<#=target.Label.Name#>"/></returns>
public <#=target.Label.Name#> <#=exit.Label.Name#>(Delegate descriptiveAction, params Object[] args)
 string text = MethodToText(descriptiveAction, args);
 Step s = new Step("<#=prefix#>", <#=Indent(exit)#>, text, () => descriptiveAction.Method.Invoke(descriptiveAction.Target, args));
 return new <#=target.Label.Name#>(s, this);

 This allow us to create expressions like the following:

Story("Something").When(Delegate.Create(this.GetType(), this, "MethodWithMoreThanFourArgs_A1_A2_A3_A4_A5"), v1, v2, v3, v4, v5);

Yes, I know it's a bit ugly, but it works just fine.

I also would like to know if someone has a better way to do this.

Mar 1, 2011 at 9:21 PM

Are you using .NET 4 or 3.5?

.NET 4 has support for up to 16 type arguments to the Action delegate, so you can just tweak the upper limit in the t4 template's for loops. I'll get around to dropping .NET 3.5 support at some point, at which point we can ship StoryQ with that built in. In the meantime, a fork is an excellent choice.

Mar 1, 2011 at 10:14 PM

We're using .NET 3.5 for now.

Unfortunately no plans to upgrating to 4.0 in the foreseeable future.

But I need to make a rollback, it didn't quite worked out as I planned.

The MethodToText threw an exception. I didn't have time to dwell further into it, though.