Using FubuMVC - Day1

There is a change request coming which requires some software to fake an external system. It should be usable by testers in order to exercise the use cases. A nice situation to finally test fubu mvc, the swiss army knife (factory) for friends of MVC Web frameworks. The following is partly backed up from my twitter timeline, partly backed up from my memory and stitched up with some good will.

  • ~10:30 – I still have a fubu copy hanging around in my github directory, so I do ‘git pull master’
  • ~10:40 – many batch files! bottles? storyteller? wai… documentation situation (and some blog posts) is still, hm, not optimal, and apparently I’m not awake yet. InstallGems.bat works without problems and installs something to zip and albacore. This works because I installed ruby at some point.
  • ~10:50 – I’m too daft to run rake. I try rakefile.rb, which is not the way it works. (Frank from 20:00 - Just type ‘rake’. Really, it’s not that hard)
  • @emilcardell chimes in. He did say that I should run rake. So I can’t complain, can I?
  • ~11:00 – Opening Visual Studio, run build – success! Setting startup project to FubuMVC.HelloSpark – success!
  • ~11:15 – Having a laugh about the Hello World Spark. Strange stuff going on there, in what you see in the browser as well as teh codez. A short question to twitter clarifies that @RobertTheGrey is the one to be held accountable! He offers help in case I’m stuck, it must be partly bad conscience, partly because he’s a good guy (A Gandalf reference surely wouldn’t be made by a bad person?)

image

  • Shortly before lunchtime – Created my first fubumvc project, which basically follows the layout of HelloSpark. Bootstrapping a fubu app is pretty clean stuff these days, but to a beginner the wealth of the internal bootstrapping DSL is daunting. Please do follow the Hello* Apps, otherwise you will get lost too easily. Yes, I see the Home View/Action I defined, nice moment to go and eat.
  • ~14:00 – Learning one or two new things about the Spark View engine. I had used it for this blog, but it just keeps bringing in good stuff, I’d say a clear case of dev eating his own cooking.
  • ~15:00 “Land of Confusion” Did I mention it wasn’t my best day? First I got confused
  • that the Home action I defined didn’t show up through the conventional url routing of controller/action. Why not?!If you’ve turned on fubu diagnostics you will get a diagnostic page under “/_fubu” – this alone should let you seriously consider this framework, because that’s a really useful feature. It shows you many aspects of your app, for example which url routes the system knows. It has to do that because the ways in which you can shape the ways in which fubu wires up your code (did you notice that element of meta here? If a framework doesn’t let you speak meta-sentences, consider that it may actually just force you to do it “my way”). The point is, the action was already wired as Home-Action, and is hence not considered by other policies that dictate how actions are exposed via urls. Does it mean that one action is only reachable through one route? Somehow I doubt it, but right now I don’t know.
  • by the Input Models of the controllers/actions. I could see in sample apps that form element values were transferred into the input model, but what with url routes, stuff we know from asp.net mvc like “/customer/{id}” …* ~16.00 – Interactions with committers to the fubumvc framework, Robert and Jeremy Miller, who kicked in delayed (timezone, that strange thing that imposes a rhythm on the Internet) – result is a gist which may be deleted sooner or later.
  • ~16.00 - 16.10 Got the shit beaten out of me at table footie (10:1, 10:3) – WTF?! Seems my mind was hard on fubu.
  • ~17.00 Fumbling with understanding input models. That’s an area where I find some guidance in docs/blog posts/sample apps lacking. Well, the result was that by all the magic for one day I lost the instinct to judge whether a framework could or could not do a certain thing. I forgot fubu to tell how to map a UrlPattern to an action. Such a pattern then defines how values of the route end up in an input model. One simple way to do that is to use the UrlPattern attribute on an action: <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:a9fc1f2d-0984-4841-9243-18b538fd9cc8" class="wlWriterEditableSmartContent"><pre name="code" class="c#">[UrlPattern(“gna/{HelpId}”)] public HelpViewModel SomethingElse(UrlHelpInput input) { return new HelpViewModel { Title = “Hello from Controller! “ + input.HelpId }; }

public class UrlHelpInput { [RouteInput] public string HelpId { get; set; } }</pre></div>

Now that worked!

  • ~19.00 (Home) – Virtually all things can be solved conventionally in fubumvc, hence my question to Jeremy:“It totally makes sense,just not my day.Do u have a convention in the system like all public props,in their seq of reflection?” (referring to mapping an input model automatically to a Url route) . Jeremy’s answer wasn’t fully parseable by me, but I sort of interpreted it that it doesn’t make that much sense since some values may be filled by a form. Regardless, I wanted to try out whether it would be possible, and, well, it is.

The following was just hacked into the UrlPolicy I had defined to dice routes out of the application’s actions:

public class TheAppUrlPolicy : IUrlPolicy
{
    public bool Matches(ActionCall call, IConfigurationObserver log)
    {
        return call.HandlerType.Name.EndsWith("Controller");
    }

    public IRouteDefinition Build(ActionCall call)
    {
        var route = call.ToRouteDefinition();
        route.Append(call.HandlerType.Name.RemoveSuffix("Controller"));
        route.Append(call.Method.Name);

        if (call.HasInput && call.InputType().Name.StartsWith("Url"))
            AddUrlPattern(route, call.InputType());

        return route;
    }

    private void AddUrlPattern(IRouteDefinition route, Type inputType)
    {
        var props = from p in inputType.GetProperties()
                    where p.CanWrite && p.CanRead && p.GetCustomAttributes(false).Any(o => o is RouteInputAttribute)
                    select p;
        foreach (var p in props)
            route.Input.AddRouteInput(new RouteParameter(new SingleProperty(p)), true);
    }
}

The IUrlPolicy is a fubu mvc interface and (an) implementator(s) can be registered at bootstrap-time. The basic code is copied form the HelloSpark-App, line 14 introduces a check whether the action has an input model defined and whether it starts with “Url”. If that’s the case, we iterate over all properties with getter and setter that are attributed with RouteInput and we add it to the defined route through a method available on the route definition. And you know what? That works. With that I concluded my first day with fubu.

Conlusion

  • steep learning curve! If aspnet mvc costs you work, I’d say don’t bother. The “getting into” phase is a bit rougher than some other stuff out there
  • That says nothing about the quality of the code. Just turn on diagnostics and go to /_fubu.* Do you want freedom in shaping your app the way you want it to? Do you hate cruft and incantations? Then that may just be for you!
  • On several occasions I had to look into the code to understand what something may do or why something doesn’t work. If you are afraid of doing that, or loathe navigating a highly structured codebase, then this may not be for you (right now, with regard to documentation).
  • I got help from several people on twitter who I know to be contributors or at least users of fubumbc. I hope I didn’t stretch their patience too much (I mean, we all have work to do, right?) but I have found it helpful and a good experience. Thank you!

 

Looking forward now to getting an app done with fubumvc. I’ve already spotted a couple of interfaces that tickled my fancy!

Chronology

  |  
comments powered by Disqus