«

»

Nov 19

On my way towards a skinny controller – ASP.NET MVC

A learning curve

My first attempt at writing a programming blog. Excuse the rambling, I’m a blogger work in progress.

Being new to the whole MVC programming concept and to be honest web progamming in general the learning curve to get up to speed and produce an enterprise solution has been pretty intense. This year, I took on that challenge and must say, it’s been an enjoyable experience. The new challenges when writing web applications and a RESTful application has meant to some degree a shift in the way I have often written my software.

When starting on my MVC project I quickly decided to adopt the MVVC (Model View Viewmodel controller) architecture. Well, when I say I, it was actually a decision discussed and decided upon by a team of 3 programmers after disecting the problem domain and realising that we all had potentially different strengths and capabilities to add to the project.

My core role of the project was in developing the controller aspects and providing the glue between our front end developer and our database provider developer who was also building some of the framework. With gusto I immediately got to work. Of course this initially meant spending a bit of time reading up on MVC itself. With my head buried in books and my hands beaving around on Google to find articles I gained a rudimentary grasp of how it all fitted together and what I might need to do.

My first decision I made was in deciding the types of controllers we were going to use. I had done a bit of reading and there was quite a following for having controllers with a small amount of actions specific to it’s problem domain. I must admit that although tempting I was swayed by our domain model which was already constructed and to a certain degree mimic’d allowed a good mapping direct to our controller and action setup.

What we ended up with is a structure that in a conceptual way outlined the class hierachy of our domain model. We used areas to defined the top level concepts and our controllers were the concrete class representation of these. The controllers themselves then had actions which encapsulated some of the core functionality and information we were trying to capture. For example one our sections became:

Area: Animals
Controller: SheepController
Actions: Numbers, Movement, Production

We had other controllers for other animals and their particular actions. Sometimes these were shared but with specific implementations and sometimes not.

And to my problem

Now this was all good. We had a basic structure. We were using view models to communicate with the UI. We had a domain model to work with and and database layer provided by a provider model. Let the coding commense…

Hack hack hack. Cough cough, backspace backspace. Hack hack. And away I went. My hands typing faster than a fighter jet going sonic.

I take a rest and evaluate what I have accomplished, preening my feathers with how well I’ve done. However what I discover quickly dampens the excitement and brings me back down to reality. My controller actions are massive. The containing code doing all sorts of things from building queries to run against the dataproviders, doing complex mappings from my domain model to the view models and even doing some validation on the data that has been provided. Building error strings and much much more. What ended up was a spagetti of a mess tidily coupled into each action method. At this stage I wasn’t too happy about this so I decided to do a bit of research and come across a commonly thrown around term “Skinny controllers”. Now that sounded like my cup of tea. But where to start?

Determine an objective

Done. My objective was to make my actions responsible to the where not the how. By this I mean they were responsible for knowing which objects were required to undertake a task, not how that task itself was implemented.

Determine the different functionality

For our particular solution we have ended up having an action method for both a GET and a POST request. This means that those two requests were to provide uniquely differing functionality.

GET: Responsible for building up the view model to be passed to the view
POST: Responsible for checking any errors on the posted viewmodels. It would also be responsible for conducting the mapping from the supplied view models to our schema model and running any business rules once that data had been copied.

A service layer

What I ended up concluding was that I needed a service layer to be responsible for knowing the how in three key functional tasks of my actions. The building up/construction of the view model, the building up of the schema model, and the validation of the schema model.

Hence my GET methods in 90% of the actions ended up being something like:

[HttpGet]
public ActionResult GetAnimals(int id) {

    var viewModel = new AnimalsService(id).GetViewModel();

    return View(viewModel);
}

or

[HttpGet]
public ActionResult GetAnimalsForFarm(int id) {

   var animals = Repository.Fetch<Animals>(id);
   var viewModel = new AnimalsOnFarmService(id, animals);

   return View(viewModel);
}

My posts would be slightly more complicated but only in that they needed to do a bit more:

[HttpPost]
public ActionResult GetAnimals(AnimalsViewModel viewModel, int id) {

    // Precheck viewmodel applied business rules
    if(!ModelState.IsValid)
       return ErrorOnView();

    // perform an update on our model from the data supplied in the viewModel
    var service = new AnimalsService(id);
    service.UpdateModel(viewModel);

    // after the update ensure the data supplied passes all business rules
    var errorHandler = CreateErrorHandler();
    if(!service.Validate(errorHandler))
       return ErrorOnView();

    // save our changes and redirect to the next or current action as required
    return CommitAndRedirectToAction(viewModel);

}

Of course this this a simplistic version of what I typically did and in some cases there might have been a couple more steps to get the write information required by the service layer. However most actions followed the same conventions and steps I would be requiring to perform.

The basic idea I tried to follow was to ensure the controller actions remained slim and skinny (lovin these buzz words) and that they were responsible for pulling together the various objects required in order to perform the desired action and not responsbile for knowing the how that bit of functionality actually performed.

Of course being my first MVC experience this may be completely off the rails. However for the particular project I was working on it seemed to work quite well. Our service classes tended to be fairly large at times but it did mean that I could write the unit tests before we had even written the view or code itself. I had tossed up the idea of breakng the service classes into their own classes for Update, Get and Validate but that seemed overkill in creating a huge amount of classes. And often the functionality required was shared anyway beftween the various methods so I decided to leave them as is.

I had thought about DIP for the controllers themselves as well but again this didn’t seem so important as the controllers were responsible for the where so were actually performing the injection into our service layers.

I had looked into some current code bases for performing the update however our domain model was fairly complex and I did not have much control over that. It seemed easier to do that manually. Of course if we were to do something along the lines of using MVC updatemodel or an external party this could easily be incorporated into the service layer.

And so I sat back and took stock of my rejigging and prodding of my first MVC application. Plenty of room for improvement and learning but hey. MVC3 is out now and 4 won’t be far around the corner. I’m sure Microsoft will come to the party and provide a host of handy libraries and features for me to learn, so no point spending too much more time here.

Time to move on to my couch and TV remote, sit back and flick through some sport on the box. Thanks for reading my first post ever on programming. Hope it helped people either in structuring their first MVC app or the opposite and helping them determine what NOT to do 🙂

Leave a Reply

WordPress spam blocked by CleanTalk.