Friday, March 5, 2010

The Rules Engine and the Command Engine

I ran into a little issue the other day...

The CMS application I am working on needed a URL builder, which combined a root directory, an optional subdirectory, and a file name. Aspects of the URL must be validated after construction, such as not allowing invalid characters.

I created two CmsUrl engines - one that processes commands, and one that processes rules. The command engine required a concrete object, since the commands modified the URL. However, this became an issue because ICommand demands an Execute method with no parameters and no return value. Therefore, the only way to get my URL string into the Command is in the constructor. Additionally, command executing cannot return a value, so the command must be acting on a reference or global string of some sort. Right? (I read a post somewhere [StackOverflow?] that said simulating reference pointers in C# was accomplished by passing a reference to the containing object, which got me to thinking on different terms.)

In most situations, I think of commands as acting on a data store. The command encapsulates all information needed to make a change on the data store. The data store exists outside the command, obviously, but the command knows how to get to it and modify it. When it comes to strings, they are usually passed by value. To relate it to the data store example, it would be like copying the entire database into the command for modification.

Well, what I ended up doing was Dependency Injection - injecting the engine into the command, and the engine holds the URL to be modified. The command then acts on the URL in the engine. The Process method on the engine has an output parameter which returns the modified URL (correct extension added to the file, etc). That seemed to simulate the data store example.

With the Rule engine, it's only job is the throw Exceptions if the rules aren't met. There is no modification of the string. So it was implemented as a static class. I don't know if that was right or not, to make one static and the other concrete, but that's what I did...

1 comment:

  1. Well, after getting some response on StackOverflow, it seems my understanding of the this keyword was incorrect - when you use this, it actually passes the reference, not a copy of the reference. So it worked as expected without a reference parameter.

    ReplyDelete