Tuesday, March 23, 2010

Using FubuMVC.UI in asp.net MVC : Getting started

If you are not fortunate enough to be able to use FubuMVC but are fortunate enough to be using asp.net MVC, you may find yourself unendingly vexed by the suckyness of the ui helpers in asp.net mvc ( heretofor referred to as mvc ).  mvccontrib has some good stuff with the uibuilders, but I find the FubuMVC.UI more to my taste.  In this post or series of posts I will show how I am using the FubuMVC.UI in my MVC app.  I am using Structuremap as my DI container so there may be a few differences if you are not.  And to that not, I got a big leg up from RyanOhs post Using FubuMVC’s Html Conventions in Microsoft MVC which seems to be dead now but may someday return so I linked to it anyway.  He’s using Windsor as his DI container.  Now on to the meat.

One of the central ideas in the FubuMVC.UI is that there are three kinds of elements were interested in.  Inputs, Labels, and Displays.  Inputs being any kind of element that allows you submit information, Labels being, well, labes and Displays being elements that display information.  Readonly information.  Labels are the easiest.  Once you know how you like to display your labels you can specify that concvention and largely be done with it.  Displays too can be pretty easy too but can get more complicated depending on what you want to display.  Inputs are the proverbial money shot.  That is where most of the cool stuff happens.

One of the first things you’ll need to do is create a set of conventions.  The idea is that you say ok whenever I specify a label ( e.g. Html.LabelFor(x=>x.FirstName) ) render it like this.  So for my convention I have

Labels.Always.BuildBy(req => new HtmlTag("label").Attr("for", req.Accessor.Name).Text(req.Accessor.FieldName.ToSeperateWordsFromPascalCase()));

So for labels always build using a “label” tag, set an attribute “for” equal to the name of the property and set the text of the label to the Property name and ( using a little extension method I build ) separate the words of the Property.  So my property was FIrstName.  it will render <label for=”FirstName” >First Name</label> . 

Similarly I do something for the display.

The fun happens with the InputFor.  To keep this simple I will show the very least that you will need for Input. 

Editors.IfPropertyIs<bool>().BuildBy(TagActionExpression.BuildCheckbox);

Editors.Always.BuildBy(TagActionExpression.BuildTextbox);

Here if you do something like this Html.InputFor(x=>x.IsReallyCool) you will get a checkbox since IsReallyCool is a bool.  and if you do basically anything else you will get a textbox.

So the final very bare minimum HtmlConvention file would like this

public class FlywheelHtmlConventions : HtmlConventionRegistry
    {
        public FlywheelHtmlConventions()
        {
            Editors.IfPropertyIs<bool>().BuildBy(TagActionExpression.BuildCheckbox);
                      Editors.Always.BuildBy(TagActionExpression.BuildTextbox);
            Displays.Always.BuildBy(req => new HtmlTag("span").Text(req.StringValue()));
            Labels.Always.BuildBy(req => new HtmlTag("label").Attr("for", req.Accessor.Name).Text(req.Accessor.FieldName.ToSeperateWordsFromPascalCase()));
        }

This is won’t take you very far but we can go over some more interesting conventions later.

Next

You will also need some extension methods that you will access the FubuMVC.UI with from the view.  Now here I chose to write the extension methods off the HtmlHelper despite the fact that it’s a big bloated pos.  I did this for a very important reason.  If you use partials you will need to be able to get information off the model from the view that called the partial from with in the partial.  So inside the partial your calling InputFor(blah).  You will know that blah is on the BlahViewModel, but you wont know that the BlahBlahBlahViewModel called that partial unless you dig around in the HtmlHelper.  More on this later. probably.

So here are the three extension methods you will need and a little helper method.

public static class FubuUIHtmlExtensions
   {
       private static ITagGenerator<T> GetGenerator<T>(HtmlHelper<T> helper, Expression<Func<T, object>> expression) where T : class
       {
           TagGenerator<T> generator = ServiceLocator.Current.GetInstance<ITagGenerator<T>>() as TagGenerator<T>;
           generator.Model = helper.ViewData.Model;
                     return generator;
       }

       public static HtmlTag InputFor<T>(this HtmlHelper<T> helper, Expression<Func<T, object>> expression) where T : class
       {
           ITagGenerator<T> generator = GetGenerator<T>(helper, expression);
           return generator.InputFor(expression);
       }
       public static HtmlTag LabelFor<T>(this HtmlHelper<T> helper, Expression<Func<T, object>> expression) where T : class
       {
           ITagGenerator<T> generator = GetGenerator<T>(helper, expression);
           HtmlTag tag = generator.LabelFor(expression);
           return tag;
       }

       public static HtmlTag DisplayFor<T>(this HtmlHelper<T> helper, Expression<Func<T, object>> expression) where T : class
       {
           ITagGenerator<T> generator = GetGenerator<T>(helper, expression);
           return generator.DisplayFor(expression);
       }

}

basically each of these is getting a TagGenerator and calling either input,label, or display on it.

The Generator method gets a TagGenator from the servicelocator( container ).  You then pass the instance of the viewmodel into the TagGenerator. Essentially the TagGenerator will read you conventions decide what to render and do so using the data in the Model.

The last step is to register some stuff with your container. 

First in your ContainerRegistry you should do as follows ( for structure map.  of windsor check out ryanohs post )

For<HtmlConventionRegistry>().Add<MYHtmlConventions>();
            For<IServiceLocator>().Singleton().Use(new StructureMapServiceLocator());
            For(typeof(ITagGenerator<>)).Use(typeof(TagGenerator<>));
            For<TagProfileLibrary>().Singleton();

Then after you call bootstrapper for Structuremap in the application.start you should call

            ServiceLocator.SetLocatorProvider(() => new StructureMapServiceLocator());

            var library = ObjectFactory.Container.GetInstance<TagProfileLibrary>();
            var conventions = ObjectFactory.Container.GetAllInstances<HtmlConventionRegistry>();
            conventions.Each(library.ImportRegistry);

Here we set up the ServiceLocatorProvider. then we get an instance of the TagProfilerLiberary and an instance of our HtmlConventions and call Library.ImportRegistry on each of the conventions.

Now in our view we can do <%= Html.LabelFor(x=>x.FirstName) %>  <%= Html.InputFor(x=>x.FirstName) %> and get

<label for=”FirstName”>First Name</label><input type=”text” name=”FirstName” value=”Cannibal” ></input>

There.  I made it through.  This looks like total ass in my editor and I may need to figure out how to display code better and redo this post.  But in any case in future posts I will go over more useful conventions and some advanced stuff.

Friday, January 29, 2010

Post Classifications

Congealed Thoughts

I enjoy a  sort of steam of consciousness style post as it helps me gel my thoughts.  However, I can only imagine that it’s pretty annoying to read.  So I am going to start sub heading my posts with a classification.  So Stream of Consciousness for that type.  Perhaps Congealed Thoughts for my opinions and thoughts that have are more ready for the masses :).  and a third for explanatory posts, explaining certain technologies and such. I’ll have to come up with the heading for that when I actually write one.

Wednesday, January 27, 2010

My venture into OOP Javascript pt3: us an M? I think so.

The next issue that I’m struggling with is the idea of a model.  Do I want to break away from the dom completely.  An event is issued from the dom to the controller.  the controller could then query the dom for all the data it might need to process the call put it in a little viewmodel and pass that around to all the services that will eventually need to deal with this data to validate and persist etc.

Yes I do like this idea.  A clean break from dom for some clean javascript programming.  Fuck another massive re write.  I’m never gonna finish this shit.   Anyway,  there’s a certain voice in the back of my head wondering if there will be inefficiencies the further I get from what I’ve always though of as javascript programming and the more I impose my server side code patterns onto my client side programming.  But I guess I’ll blow that up later.

My venture into OOP Javascript pt2: MVC?

At this point I’ve tried to break out the code into classes that loosely mimic my MVC classes.  A view that deals with setting up the calendar onload with the proper dropdowns and so on, a controller that deals with the events or “actions” that come from the calendar, and various services. 

One immediate issue that comes up is that  while the calendar is the starting point, once you click on it you get a dialog box which is not unlike an entire new and mostly unrelated module that has all manner of view setup, events or “actions”, data, rules and services.  It’s almost like whenever an event or a time is clicked it the calendar controller should call a calendarEventController with it’s seperate view and data.  But then I wonder if every dialog box should have it’s own controller.  There could be several stages to creating an Event.  If the event is in the past you have to justify it.  That’s one dialogbox, then you get the regulare add/edit dialog, if it’s edit and recurring you have a new dialog asking if you want to change all future events or just this one. and so on. 

Ok so upon writing this it’s starting to make me think about fubumvc’s “controller-less actions”.  basically it does away with the idea of a proper controller and makes each action it’s own class.  This class references the view it wants to write to and the model it’ll use.  However, I’m not sure I want to use this pattern in Fubu, much less in my javascript code.  I mean views generally have several calls that are all related and if each call requires it’s own class/controller then things can get kind of dispersed.  Hmmm.

My venture into OOP Javascript pt1

So I’m trying to wrap my head around javascript programming.  Not so much jquery this or modify that, so much as full on client side functionality. 

I’m building a scheduling calendar using jquery.jqweek or something like that.  Basically looks like a google calendar.  But there is a great deal of functionality that I have to add in order for it to display correctly ( with the information I want displayed that is ) and for the adding and editing appointments.  A LOT of functionality.  So I’ve been struggling with the best way to organized my code and as it gets more organized I start seeing patterns that are familiar to my C# code, as well as patterns that are completely different.

My venture into OOP Javascript pt4 : Linear vs cyclical

Yet another issue that comes up is that ultimately you end up wanting to persist data and or retrieve data.  In server side code this is done synchronously.  You query the db and wait for the return.  In client side code, this is generally done via ajax.  which is, as per the a, asynchronously.

This completely disrupts the flow of the app.  Instead of a method calling for some data, receiving it, and then processing it, you have to create a method for processing the data, then pass that method into the call for the data ( to be used as the call back from the ajax call ).  This is kind of topsy turvy and makes things more linear.  Less circular.  Instead of having method calls nested in other method calls walking down a chain then back up the chain and ultimately returning home to the original caller, I do a little of that but ultimately do off on a branch never to return. 

I would very much like to find a way around that since it is completely counter to what I am used to, but more likely then not I will just have to create/find some patterns for understanding it and using it more efficiently.

See if I could bring it all home to the controller then I could have the controller be the only point of contact with the dom.   However if there are end points all over hell then the will each have to have contact with the dom . Or perhaps I could have a “dom touching service” where I keep all my end point code.  Hmmmm. again.

Thursday, January 21, 2010

RubyMine Rocks

RubyMine is the shit.  I don’t develop in ruby.  But I do do a lot of javascript.

As we all know Visual Studio is completely untenable for javascript. I know that you can down load this and install that and eventually it wont be a piece of shit, it’ll merely suck but I’ve tried and failed and couldn’t give a shit to try to man handler That app into doing it’s job.

In comes Jet Brains RubyMine.  Or at least into my life, It’s been around for a while.  Anyway, this app just further proves the point that Visual Studio is merely a shell for running Resharper.  I use RubyMine for my javascript and I get most if not all the wonderfulness that is Resharper.  I can click on function calls and be taken to the definition and vise versa, rename, refactor the whole nine yards.  It’s just awesome.  It even has great intellisense.  No longer do I feel like I’m developing in the dark.  Or worse that I have to use my brain to keep track of everything.   I don’t know about you but after the ‘70’s I need all that’s left of my brain for the important stuff. Logic and porn. 

One caveat is that RubyMine takes a little tweaking.  However, I have used several other javascript editors all of which required a ton of tweaking just to be usable and all in all seemed like big heavy unweildy messes.  RubyMine feels a lot cleaner, lighter and easier to manange, and once you get all your settings tweaked it’s just like writing C#. … Except for all the differences, but you know what I mean.

I am currently refining my settings daily and will post them here if anyone is interested. 

Also it costs $100.  So that kinda sucks but so does resharper and would you even consider developing with out that?