Code of the week

This piece of code make me so happy:

private static IDictionary<string, Func<Stream, ICommand>> commandFactories =
	new Dictionary<string, Func<Stream, ICommand>>
		{
			//storage
			{"add", s => new AddCommand(s)},
			{"append", s => new AppendCommand(s)},
			{"cas", s => new CasCommand(s)},
			{"delete", s => new DeleteCommand(s)},
			{"prepend", s => new PrependCommand(s)},
			{"replace", s => new ReplaceCommand(s)},
			{"set", s => new SetCommand(s)},

			// retrieval
			{"get", s => new GetCommand(s)},
			{"gets", s => new GetsCommand(s)},

			//modifications
			{"incr", s => new IncrCommand(s)},
			{"decr", s => new DecrCommand(s)},

			//misc
			{"flush_all", s => new FlushAllCommand(s)},
			{"quit", s => new QuitCommand(s)},
			{"version", s => new VersionCommand(s)},
		};

This is something that I do quite often, and it is good to have a way to do it easily.

Print | posted on Friday, June 06, 2008 2:16 PM

Feedback


Gravatar

# re: Code of the week 6/6/2008 3:22 PM James L

They look like memcached commands


Gravatar

# re: Code of the week 6/6/2008 4:18 PM Alex Simkin

You should have request commands from IoC container, not from the dictionary.


Gravatar

# re: Code of the week 6/6/2008 4:20 PM Gary A

So what does it do, and why did you do it this way?


Gravatar

# re: Code of the week 6/6/2008 4:27 PM Harry M

Have I just made a DSL?

public static void Main(string[] args)
{
var me = new Person("Harry");
var you = new Person("Bob");
var options = new Dictionary<string, Action<string>>()
{
{"I", s => DoSomething(me, s)},
{"You", s => DoSomething(you, s)}
};
Parse("I say hello", options);
Parse("I jump", options);
Parse("You say goodbye", options);

}

private static void Parse(string command, IDictionary<string, Action<string>> options)
{
string[] parts = command.Split(new char[] {' '}, 2);
options[parts[0]](parts.Length > 1 ? parts[1] : null);
}

private static void DoSomething(Person who, string what)
{
var options = new Dictionary<string, Action<string>>()
{
{"say", s => who.Say(s)},
{"jump", s => who.Jump()}
};
Parse(what, options);
}
class Person
{
private readonly string name;
public Person(string name)
{
this.name = name;
}
public void Say(string message)
{
Console.WriteLine("{0} says: '{1}'", name, message);
}
public void Jump()
{
Console.WriteLine("{0} jumps", name);
}
}


Gravatar

# re: Code of the week 6/6/2008 8:29 PM Vijay Santhanam

love the dictionary lookups with the generic delegates/lambdas too.

as much as i'm interested in your code, i'm doubley interested in your design process. e.g., how much analyse/OO modelling you do before you start writing real code?

With tools like R#/svn is the up-front design pretty much dead for garage projects?

would like to read about the steps you take before you get to code. i ask because as a sophisicated practitioner, you take intermediate working steps for granted whilst someone at my level struggles to keep up sometimes.


Gravatar

# re: Code of the week 6/7/2008 12:29 AM firefly

The more I dig into C# 3.0 the more I infatuate with it.


Gravatar

# re: Code of the week 6/7/2008 7:50 AM firefly

Question...
private static IDictionary do you gain anything by using the IDictionary interface verse just using a regular Dictionary class?


Gravatar

# re: Code of the week 6/7/2008 8:15 AM Ayende Rahien

I like using the most abstract type possible


Gravatar

# re: Code of the week 6/8/2008 11:58 AM Andrey Shchekin

What about
IDictionary<string, Func<Stream, ICommand>> CreateCommandFactories(IEnumerable<Type> types) {
      return (
            from type in types
            select new {
                  Name = type.Name.Replace("Command", "").ToLowerInvariant(),
                  Factory = (Func<Stream, ICommand>)(s => Activator.CreateInstance(type, s))
            }
      ).ToDictionary(
            x => x.Name,
            x => x.Factory
      )
}

Of course better way would be to use Regex for parsing and Expression.Compile for constructor.


Gravatar

# re: Code of the week 6/8/2008 12:42 PM Ayende Rahien

That involves reflection. I wanted this to be zero reflection effort


Gravatar

# re: Code of the week 6/13/2008 10:28 AM Dmitry Gusarov

Ok, but Andrey suggested an excellent duplication removal.
I thought of it... what is more valuable? Avoiding reflection or avoiding duplication... In any case we have a tests ;)


Gravatar

# re: Code of the week 6/13/2008 1:21 PM Ayende Rahien

Dmitry,
In this case, what I wanted was no reflection. The price paid for it is worth it, I think.

Comments have been closed on this topic.