Archive for the ‘Fubu’ category

FubuMVC Behaviours II

May 9, 2010

In an older post I wrote about Behaviours in FubuMVC and tried to show how fubu can handle different concerns of your website. Now, while the post still is a good example of what we can do with fubu, especially regarding scenarios where mutual concerns of several pages (across the application) can be handled through one sole class (thus encouraging SRP), the solution I suggested in the post to the problem I’ve discussed was far too complex and inefficient compared to what can be achieved by the following way simpler solution.

Let’s work our way from bottom to top. First we’ll have a view model for our Site.master page, a class that will contain all that we want to display on each and every page having this master page:

public class SiteMasterModel
 {
 public IList<Post> History { get; set; }
 }

In our Site.master page we’ll have access to the model by having such a class the from which our master view will inherit:

public class SiteMasterView : FubuMasterPage<SiteMasterModel>
 {

}

What’s left to do now is to create the Behavior that will take care of populating our blog posts History property of the SiteMasterModel, or for that matter any other master page concern.

public class MasterPageBehavior : BasicBehavior
 {
 private readonly IFubuRequest _request;
 private readonly IPostRepository _repository;

 public MasterPageBehavior(IFubuRequest request, IPostRepository repository)
 : base(PartialBehavior.Executes)
 {
 _request = request;
 _repository = repository;
 }

 protected override DoNext performInvoke()
 {
 _request.Set(new SiteMasterModel { History = _repository.GetHistory() });
 return base.performInvoke();
 }
}

StructureMap would take care of injecting the IFubuRequest and IPostRepository (or IPostService or whatever you want to have) interfaces implementations you’ve got. How simple and elegant is that? What’s left after that would be to simply register our Behavior:

Policies.WrapBehaviorChainsWith<MasterPageBehavior>(); 

Not only the behaviour registration procedure is less complex, with this solution the display would be handled from within the master page, rather than from each and every view.

On SRP and staying DRY

April 4, 2010

A couple of weeks ago Chad Myers posted a message on the Fubu group explaining the difference between Fubu and MS MVC. This was definitely an Eureka moment for me- suddenly SRP made sense to me and it all clicked into place. In his message, Chad says:

Front Controller is also
about composing the response.  Sometimes the view needs more information
than what is relevant to the “meat” of the request (i.e. displaying the
login page may involve displaying advertisements or notifications, etc that
are not necessarily the responsibility of the Login action).

The first thing that popped into my mind was the parent controller Uber class we’ve got in the project I’m working on currently. In it we deal with security and authentication issues, we deal with requests for downloading help files for each and every page in the web site, we deal with maintenance scenarios when the site would need to be down and so on. Needless to say, the number of ifs we’ve got there is starting to get rather unhealthy and the thought of making any changes to any of these responsibilities/logics makes me shudder; with fubu, we could have had a Behaviour for each concern/responsibility. Although this might be a rather extreme example of the Single Responsibility Principle (1 method – 1 responsibility), it is usually clear cut examples that make you grasp the idea fully and understand what were you doing wrong all that time.

From what I’ve experienced up until now, the first sign that makes me look for SRP violations is a forced application of the DRY principle, attempting to mutualise code/logic that seems to be similar and treating the same sort of a scenario. A great example for that scenario was a little feature I had to add a week ago, in which I was supposed to allow the users to subscribe people, while creating their program. We already had a very similar feature that allows the users of the application to subscribe people on their program after the latter has been created. My colleague thought we could simply reuse the views and actions we already created. That was a good enough sign for me to get some more explanations about the process of subscribing someone to your program while creating it, and needless to say it turned out that “it would be exactly the same thing, only…” and this ‘but’ made changes to some data access logic we had and the way we use NHibernate to get this data. We ended up separating these two scenarios and the best thing is that we’ve gained a lot in doing so in terms of maintainability 🙂

My DSL experience

March 20, 2010

A couple of days ago my recent pull request for FubuMVC has been accepted- a feature I’ve been working on that allows registering through conventions the partial view that would be used for a certain partial model. This meant writing some DSL which was a first time for me.

In case anyone stumbles upon this entry and wants to find out more about what is DSL and how to do it properly, I will recommend you to head straight towards Jeremy D. Miller’s thorough article on the subject.

My target was simply to allow the developer to write

 types.For<MyPartialModel>().Use<MyPartialView>();

In order to do that I added the following:

  1. IPartialViewTypeRegistry
  2. IPartialViewTypeBindingExpression
  3. IPartialViewTypeRegistrationExpression

The registry would register each partial model type to its partial view type, the latter being a page (implementing IFubuPage). At first I had my registry containing also the For method which passed the partial model type and returned a binding expression which contains only the Use method so that the user could only tell the registry to use the view for the model (so that the Use method was ‘void’).

Afterwards I added the registration expression in order to hide the registry interface. The registration expression contains only the For<TPartialModel>() method.
Inside the FubuRegistry I added then the following method:

public void RegisterPartials(Action<IPartialViewTypeRegistrationExpression> registration)
 {
 var expression = new PartialViewTypeRegistrationExpression(_partialViewTypes);
 registration(expression);
}

That way, the IPartialViewTypeRegistry instance (the _partialViewTypes field) is completely hidden.

Redirecting in Fubu

March 6, 2010

This is a very straight forward post, just a reminder of how do you redirect and transfer in FubuMVC.

Using the FubuDinner example, we have a registration page, and its GET action:

public RegisterModel Query(RegisterModel input)
 {
 input.PasswordLength = _settings.MinPasswordLength;
return input;
}

Now, in our POST method we’d like to log on the user and redirect to our Home page if the registration went ok (validated and persisted); however, if the registration wasn’t validated, we’d like to get back to our registration page, display the error messages and keep the data the user has entered.

This is how the POST method would look like than:

public FubuContinuation Command(RegisterForm input)
 {
 var errors = _validator.Validate(input);

 //TODO: need unique username validation

 if( input.Nerd.Password != input.ConfirmPassword )
 {
 errors.RegisterFailure("ConfirmPassword", "Confirm password must match password exactly.");
 }

 if( errors.IsValid())
 {
 _repository.Save(input.Nerd);
 _authContext.ThisUserHasBeenAuthenticated(input.Nerd.Username, false);
 return FubuContinuation.RedirectTo(new HomeModel());
 }

 return FubuContinuation.TransferTo(new RegisterModel { Errors = errors, Nerd = input.Nerd, ConfirmPassword = input.ConfirmPassword });
}

Simples!



FubuMVC Behaviours

February 21, 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());

FubuMVC – No Strings Attached II

February 8, 2010

In my last post I was talking about how stringless fubuMVC is and how it simplifies our work.

One of the points I was still struggling with was how to add a convention to add a certain route pattern; in other words, I was trying to figure out what was the Fubu equivalent to ASP.NET MVC’s

routes.MapRoute(
 "Default", // Route name
 "{controller}/{action}/{id}", // URL with parameters
 new {controller = "Home", action = "Index", id = ""} // Parameter defaults
);

Well, it seems that this is way more simple than I thought.

The first thing you have to do is write an interface for all your models with an Id property, something along the lines of:

public interface IIdentifiable
 {
 int Id { get; set; }
 }

Now, for each and every InputModel you wish to have the Id in the url as shown above (controller/action/Id), you’ll need to implement your IIdentifiable and then in your FubuRegistry class, you add the following:

Routes.
IgnoreControllerNamespaceEntirely().
ForInputTypesOf<IIdentifiable>(x => x.RouteInputFor(model => model.Id));

And that’s it!! Magic, isn’t it?

What I personally love about it is the fact that a) no strings, yet again, but more importantly- b) you don’t have to struggle with the much less intuitive api of ASP.NET MVC that forces you to write the more specific routes before the more general ones. Fubu api is by far more user friendly!

FubuMVC Routing – No Strings Attached

February 6, 2010

Recently I’ve stumbled upon FubuMVC, and thought I should have a go at it, see what can you do with it, and more importantly see how other implementations of the MVC pattern work. After following the HelloWorld in Fubu steps, I felt I really like what I see, and thought I should try and pick it up, blogging on it on my way… If everything would work out nicely, I’m hoping to write my own site with Fubu, and share with others my experience with it 🙂

So the first thing I wanted to have a look at was the way they map (or register) their routes in Fubu, the way we in MVC do

routes.MapRoute(
 "Default", // Route name
 "{controller}/{action}/{id}", // URL with parameters
 new {controller = "Home", action = "Index", id = ""} // Parameter defaults
);

And lo and behold, Jeremy Miller has posted about the subject. Now, I really like the fact that you can simply have a [RouteInput] attribute on your InputModel property, and that’s all it takes to tell the URL to end with “/{Id}”; that way, if you have the IputModel and the controller action

public class ProductsInputModel
 {
 [RouteInput]
 public int Page { get; set; }

 public ProductsInputModel(int page)
 {
 Page = page;
}
}

public class ProductsController
{

public ProductsViewModel List(ProductsInputModel model)
 {
//use model.Page to get your products list of page number X
}

}

then the url /products/List/4 will get you to the 4th page of your products list.

This, by the way, could be also achieved with the QueryString attribute, which as its name suggests, would put this data in your url as a query string like so: /products/List?Page=4

However, using attributes should come only after the convention (that is for exceptional occasions), and that’s something I still need to figure out. Doh’!

Now, what Jeremy was saying in his post (in a nutshell), is that the Fubu equivalent to ASP.NET MVC

Html.ActionLink("ActionName", "ControllerName", routeObjects)

uses no strings whatsoever, but simply uses the conventions. If we use an input model per action, we simply call

UrlRegistry.UrlFor(new ProductsInputModel(4)); 

How cool is that?? Working with ASP.NET MVC I can definitely say that this approach could have made a HUGE difference. One of the things I dread the most is renaming an action name or a controller.