Thursday, February 2, 2012

wormholes

Joel Holder hosted an informative meeting today on an approach to architecture that he has put together with Rafael Torres. Wormholes are key term in the new vision for the objects to come in our app. The way that CRUD around objects has materialized in our application has been unsophisticated so far and has come with a lot of problems. Going forward, as we start to build out the richer objects with lifecycles (the sort of objects that Eric Evans would consider entities) we want to get things right, and in particular we want to make things easier to test. Joel, pictured here, started the meeting by explaining why it was painful to have controllers interact directly with repositories in the DAL (Data Access Layer) within a Palermo Onion.

This is the traditional way to build an ASP.NET MVC app, but it is proving hard to test. Controllers are making calls to repositories and handing repository references down into models. Testing a controller requires going on a spelunking expedition for the things one needs to mock just in the name of getting a would-be test to the point where it fails instead of throwing an exception. Instead, Joel feels that controllers should have no collaborators that are managed objects (no repository references). He models his MVC approach on what he sees as a growing trend away from having controller do more than routing and he mentioned that in the node.js framework called Express that controllers were eventually renamed to be "routers" in a wise move. He feels a layer for Command Processors (light circles below) should sit between the rest of our onion and the Controllers (darker circles below) and that communication should occur through wormholes (red item below).

The Command Processors will in turn "talk" to service layers in our onion which will "talk" to the DAL and back. The wormholes make our Command Processors different than the Command Processors of Headspring which were baked before the dynamic objects of C# 4.0. The wormhole analogy suggests putting something into a tunnel and knowing that it will emerge from the tunnel somewhere, but not being able to see where from the entry point. Using the dynamic feature of C# 4.0, Joel has empowered the ability to call a method of any name on a Command Processor's DynamicCommandInvoker. If one calls .EditOrder for example, our app will try to find a file dubbed "EditOrderCommand.cs" to find an appropriate class for the "method" called, but to the controller doing the calling calls .EditOrder blind to as much. The controller calling .EditOrder basically asserts a desire to:

  1. invoke action x
  2. with model y
  3. and then redirect to z

ProcessCommand(), shown above, is the method inside any one particular command file that will do the deed and will be the one method to really test, test, test.

TempData is for redirects, and redirects only.

TempData["foo"] = "bar";

...is not going to linger as long as...

Session["foo"] = "bar";

 
 

http://stackoverflow.com/questions/1500402/when-to-use-tempdata-vs-session-in-asp-net-mvc suggests it is "for redirects, and redirects only."

things that don't suck

Wednesday, February 1, 2012

I wish there was a better way to see if a ViewBag variable existed in ASP.NET MVC 3 and 4 beyond a null check.

@if (ViewBag.ShouldShowSuccessMessage != null)

{

   ViewBag.ShouldShowSuccessMessage = null;

   <script type="text/javascript">

      showSuccess("Your changes have been saved!");

   </script>

}

It startled me to see a class in our app with numerous constructor signatures today.

I have not seen that in some time.

{ get; private set; } sabotages MVC model bindings

:(

getting used to AutoMapper

AutoMapper really helps makes the classes it maps to light and thus easy to test. Whenever I make a method in a class and then struggle to test it due to the fact that I cannot bridge the constructor in the class without mocking 101 things it is really frustrating. This is the sort of noise that does not make me want to write tests. AutoMapper helps alleviate this problem. That said, I wonder if I really should be placing a method inside of a DTO and then marveling at how easy it is to test. I probably should do the same work in a .ResolveUsing rule and just set a get-setter at the DTO, huh? I'll pick Rafael's brain when he gets in...