MonoRail: Dynamic Actions; The better way to implement actions?

We are finishing up our eight month development effort on Knowing what we do now, “What would we do different?”.I think most of my team would say; Dynamic Actions. What are Dynamic Actions?

Dynamic Actions are a way to associate code with a name in runtime.

What exactly does that mean? An example might help explain.

public ListingController(){    DynamicActions["ImageSlideShow"] =        new ImageSlideShowAction(new ListingContext());    DynamicActions["FullSizeImageSlideShow"] =        new FullSizeImageSlideShowAction(repository);}

After these actions are added, listing/imageslideshow.rails and listing/fullsizeimageslideshow.rails are mapped to the actions defined in ImageSlideShowAction and FullSizeImageSlideShowAction respectively.How does one implement a Dynamic Action?

public class FullSizeImageSlideShowAction : IDynamicAction{    public void Execute(Controller controller)    {        string identifier = controller.Params["identifier"];        Listing listing = FindByListingNumber(identifier);        controller.PropertyBag["Listing"] = listing;        controller.RenderSharedView("fullsizeimageslideshow");    }}

Why would we want to use Dynamic Actions? I will let Hammett answer this question.

DynamicActions offers a way to have an action that is not a method in the controller. This way you can “reuse an action” in several controllers, even among projects, without the need to create a complex controller class hierarchy.

The most important part of Hammett’s answer is “reuse an action … without the need to create a complex controller class hierarchy”. In the beginning or our project, we use inheritance to “reuse actions”. This turned out to be a bad decision, for all the obvious reasons. At the time, we overlooked Dynamic Actions; I think partially because the Dynamic Action documentation was buried in the advanced section of the MonoRail documentation.Our code has two main use cases that are shared among eight different domain models. We currently use one base controller to implement the use cases with hooks to allow the subclasses to customize its behavior. This has made (as you can imagine) unclear and hard to maintain code. I would never again use inheritance as a way to share actions across controllers.Has anyone else overlooked Dynamic Actions?Any advice on implementing Dynamic Actions? Any pitfalls?


One Response

  1. DynamicActions are great. They save a lot of time, and they favor composition over inheritance.

    Pitfalls: I was unable yet to decorate them with attributes the same way you can actions in a controller. Adding [SkipFilter] or [Layout] didn’t work. I imagine this will be fixed eventually.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: