Snowing Code

Personal notes on software development


FubuMVC Behaviours

(Publish date: 21/02/2010)

In an old post Mark Nijhof talked about the way Fubu can handle different concerns of your website. He explains that with Fubu we can add ‘behaviours’ in order to get certain data that needs to be displayed on certain pages in certain contexts; in other words different concerns could be treated in different places.

Suppose we want to display the list of the most recent posts of our blog. First, we should have an interface for all of our ViewModels that would have to render the recent posts list:

public interface IRecentPostsModelBase
           {
          IList<Post> RecentPosts { get; set; }
          }

and each view model that would need to display these posts would implement our interface.

 public class OutputBehaviour : BasicBehavior
           {
           private readonly IFubuRequest _request;
           private readonly IPostRepository _postRepository;
          
           public OutputBehaviour(IFubuRequest request) : base(PartialBehavior.Ignored)
           {
          _request = request;
           }
          
           protected override DoNext performInvoke()
           {
          IRecentPostsModel recentPostsModel = null;
          foreach (IRecentPostsModel model in _request.Find<IRecentPostsModel>())
          recentPostsModel = model;
          if (recentPostsModel != null)
          {
          recentPostsModel.RecentPosts = _postRepository.GetRecentPosts();
          _request.SetObject(recentPostsModel);
          }
          return base.performInvoke();
           }
          }

Now, we are going to insert our behaviour directly after the OneInOneOutActionInvoker default fubu behaviour that sets the output view model in the current FubuRequest. That way, our behaviour will be able to add/inject the recent posts into the output model view after it has been initialised, after the controller action has been invoked, but before the view has been rendered and the output model has been used:

public class MyPolicy : IConfigurationAction
           {
           public void Configure(BehaviorGraph graph)
           {
          graph.Behaviors.Where(c => c.ContainsCall(a=>a.OutputType().GetInterfaces().Contains(typeof(IRecentPostsModelBase))))
           .Each(InsertBehaviours);
           }
          
           private void InsertBehaviours(BehaviorChain c)
           {
          Wrapper node = new Wrapper(typeof (OutputBehaviour));
          c.Top.InsertDirectlyAfter(node);
          node.InsertDirectlyAfter(new Wrapper(typeof(MyBehaviour)));
           }
          }

Inside the Configure method we’re filtering the behaviours with an ActionCall having an output type implementing IRecentPostsModelBase. The graph.Behaviors property contains a behaviour per action (ie if you have only two pages with two corresponding actions, the Behaviors property would have two chains).

Last thing we need to do would be registering our behaviour in our FubuRegistry, like so:

Policies.Add(new MyPolicy());
Tags: fubu fubumvc
blog comments powered by Disqus