Ayende @ Rahien

Hi!
My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

+972 52-548-6969

, @ Q c

Posts: 18 | Comments: 63

filter by tags archive

Code of the week

time to read 1 min | 172 words

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.


Comments

James L

They look like memcached commands

Alex Simkin

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

Gary A

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

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);

        }

    }
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.

firefly

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

firefly

Question...

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

Ayende Rahien

I like using the most abstract type possible

Andrey Shchekin

What about

IDictionary<string, Func<Stream, ICommand>> CreateCommandFactories(IEnumerable 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.

Ayende Rahien

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

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 ;)

Ayende Rahien

Dmitry,

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

Comment preview

Comments have been closed on this topic.

FUTURE POSTS

  1. RavenDB 3.0 New Stable Release - 15 hours from now
  2. Production postmortem: The case of the lying configuration file - about one day from now
  3. Production postmortem: The industry at large - 3 days from now
  4. The insidious cost of allocations - 4 days from now
  5. Buffer allocation strategies: A possible solution - 7 days from now

And 4 more posts are pending...

There are posts all the way to Sep 11, 2015

RECENT SERIES

  1. Find the bug (5):
    20 Apr 2011 - Why do I get a Null Reference Exception?
  2. Production postmortem (10):
    31 Aug 2015 - The case of the memory eater and high load
  3. What is new in RavenDB 3.5 (7):
    12 Aug 2015 - Monitoring support
  4. Career planning (6):
    24 Jul 2015 - The immortal choices aren't
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats