The event driven concept in Rabbit Framework has nothing to do the one in Web Forms. It is more like the event driven in Node.js, a server-side JavaScript platform, which has more followers than Ruby on Rails on Github now.

Rabbit Framework has a site engine that implements loosely coupled event publication and subscription. Inspired by WordPress, the engine of Rabbit Framework is hook based.

From anywhere of the site, we can run a hook (like fire a event). If there is a hook implementation registered, it will be invoked. If there are multiple hook implementations, the results of earlier hook are passed into later hook giving it a chance to overwrite.

E.g. the PageStart.cshtml file runs a getlayout hook to retrieve layout file name.
@{  
    Layout = SiteEngine.RunHook("get_layout"as string;
}
The Core module loads site settings and send back the layout file name.
public static class Core
{
    public static void Init()
    { 
        SiteEngine.AddHook("get_layout", (data) =>
        {
            dynamic settings = SiteSettings.Load().Value;   
            return settings == null ? "" :
                string.Format("~/Templates/{0}/_SiteLayout.cshtml", settings.Template ?? "Default");
        });
    }
}
The hooks are implemented as call backs functions. Thanks .NET FUNC delegate and lambda expressions, writing call back functions in C# is as easy as writing them in JavaScript in Node.js.

In V 0.3.0, an attribute, called Hook is introduced to make it more .NET style than javascript style. Rabbit site engine converts the methods that have Hook attribute into call back functions.

public static class Core
{
    [Hook]
    public static dynamic Get_Layout(dynamic data)
    {
        dynamic settings = SiteSettings.Load().Value; 
        return settings == null ? "" :
            string.Format("~/Templates/{0}/_SiteLayout.cshtml", settings.Template ?? "Default");
    }

    [Hook("get_layouts")]
    public static dynamic GetLayouts(dynamic data)
    {
       //...
    }
}
The Hook attribute by default takes method name as hook name. You can override the name by setting a hook name explicitly in the attribute.

Considering a scenario of a CMS site, to load page from content storage to the screen, it fires a get_page hook. Then the storage module loads page from disk. The content filter module masks the content's bad words. The wiki module converts the wiki words to links and etc. The hooks plug all pieces together, which makes the framework highly extensible.

As mentioned above we can run hooks from anywhere. Theoretically , we can also register hooks from anywhere. But in order to make it easier to manage, the hooks are grouped by modules. We deploy and enable a module to register all its hooks, as well as disable a module to exclude all its hooks.

Modules are deployment packages of hooks.

Last edited Mar 9, 2011 at 8:09 PM by yysun, version 7

Comments

No comments yet.