Friday, July 29, 2011

Zen and the Art of Dependency Injection in MVC

Let me start off on a modest note: I am not an expert on dependency injection.
I am, however, certain of the value that it provides.

TDD

After having engaged in the same conversation time and time again, I have become convinced that there is indeed "one simple way to get any developer to write better code." That is because every developer, Junior or Senior, C# or Java, can always engage in more Test Driven Development with Dependency Injection. These are best practices that we can all agree on and that will always result in better and more maintainable code.

If you are already doing TDD with Dependency Injection, keep it up and help spread the word! If you are not, it's time to start. On the plus side, thanks to tools like NuGet, it has never been easier to get started with all of these new fun techniques. :)

Dependency Injection

Dependency Injection is a universally accepted best practice for a number or reasons, not the least of which is how easy it makes unit testing. You should be able to test one section of code without having to rely on the other 99% of your application. By injecting dependencies you are able to control what code is being tested with pin point precision.

A little ant can't move a lake, nor should it want to. However with a little help from a good surface tension framework, it can easily move a drop of water.

MVC

The MVC architecture provides you with a consistent entry point into your code: controller actions. All requests come in and get processed the same way, always passing through a consistent set of action filters and model binders. Right out of the box the MVC model binders are already injecting models straight into your controllers, so why not take it one more step forward and inject your services too?

My controller actions almost always need two things: 1) a model and 2) a service to process that model. So let the MVC model binder manage the RequestContext and inject your model, and let a DI framework manage the logic by injecting your service.

NuGet

To get started (after having installed NuGet) you need look no farther than Tools -> Library Package Manager -> Manage NuGet Packages. If you search for Ninject, a MVC3 specific package will come up that can install itself straight into your MVC3 project and get you going in mere seconds.

Ninject is just one choice of Dependency Injection framework, and it has great documentation. If you would prefer something else then just pick your flavor of choice and keep on moving.

Example

Create your controllers, models and services like normal, and update your controller to take in a service dependency through it's constructor.

public class CalculatorController : Controller
{
     public ICalculatorService CalculatorService {get; private set;}
     public CalculatorController(ICalculatorService calculatorService)
     {
         CalculatorService = calculatorService;
     }

Then all that you have left to do is create a model that binds the service type to it's interface...

public class MvcExampleModule : NinjectModule
{
     public override void Load()
     {
         Bind<ICalculatorService>().To<CalculatorService>();
     }
}

...and load that in the static RegisterServices method.

public static class NinjectMVC3
{
     private static void RegisterServices(IKernel kernel)
     {
          var module = new MvcExampleModule();
          kernel.Load(module);
     }

That's it. That is all that you have to do to start using Dependency Injection.
Want proof? Download the sample application.

Enjoy!
Tom

Sunday, July 17, 2011

How JSONP Works

So recently I was having a conversation with someone about my JSONP update for the ExtJS library. We were talking about how I added error handling to their default implementation, and exactly what trick I had used to do that. However, we should probably start at the beginning...

What is JSONP, and how does it work?

JSONP is a standard (a hack really) that allows you to make AJAX requests across different domains. While this is an obvious security risk, there are also times where do right necessary.

Your browser appends a script block to your webpage that points to the foreign domain. Because of this, the JSONP request must be a simple get request that returns raw JavaScript.

So, what's the catch?

The return format for the JSONP request must be in the form of a call to a single global function. Once loaded, the script will execute and immediately call the global handler, which should know how to get the request data back to its caller. Also, depending on your browser, the script block may fire an onload (or in the hacky IE world, an onclick) event to help get the data back to its proper location.

The even trickier part is error handling, as there are no universal events to report script load failures.

Error Handling with JSONP

Ok, we are finally back on topic! As far as I know there are only three basic solutions to this problem...

Bad) No error handling at all.
Obviously this is a crappy solution, but it is what the default ExtJS implementation does. Somehow I suspect this lack of error handling support is 'justified' by saying that you shouldn't be using JSONP in the first place.

Better) Check for success after your max time out.
This is what my ExtJS implementation does. Before the request is made I set a timeout to call back 1 second after the max timeout of the request. The global handler calls a function that updates the JSONP request queue, canceling the timeout. If the time out is not canceled, it is assumed that the request failed and an error handler is called. This is much better than having now error handling, but it is still rather mediocre, as it could cause your end user to wait 30 seconds to find out about an error that happened 29 seconds ago.

Best) Wire up to state change events for the script block.
This is what the jQuery JSONP plugin does. Obviously this is the best solution, as it is using events exactly as they are supposed to be. The problem of course is that it has to support all the different browsers and all their different events.

In Summary

JSONP is useful, and is pretty easy to use. Implementing your own client side JSONP solution is kind of tricky, especially when taking error handling into account.

I have been trying to update my JSONP implementation to support additional error handling events, but so far it has proven to be rather difficult. Hopefully we'll see a 3.0 in the not too distant future, but right now I need to go watch the 2011 Womens World Cup Final! :D

~Tom

PS: Hopefully I will get the opporutnity to talk about this at SenchaCon 2011 in Austin TX...so if you haven't yet, go sign up!

Saturday, July 2, 2011

Another CodeSmith DNUG Tour Update!

On the road again, I just can't wait to get on the road again! The life I love is making code with my friends, and I can't wait to get on the road again!

Dates

  • New York
    • July 6th - Fairfield DNUG - Code Generation
    • July 7th - Long Island DNUG - Code Generation
  • Texas
    • July 12th - College Station DNUG - PLINQO
    • July 26th - Dallas ASP.NET UG - Attack of the Cloud
    • August 12th - Dallas TechFest - Attack of the Cloud, Embedded QA
    • October 23rd - Austin, SenchaCon - (Pending Approval)
  • Louisiana
    • August 6th - Baton Rouge, SQL Saturday - PLINQO
    • August 8th - Shreveport DNUG - Attack of the Cloud
    • August 9th - New Orleans DNUG - Code Generation
    • August 10th - Baton Rouge DNUG - Code Generation
    • August 11th - Lafayette DNUG - Code Generation
  • Utah
    • September 8th - Salt Lake City, Utah DNUG - TBA
    • September 10th - Salt Lake City, Utah Code Camp - TBA
    • September 10th - Salt Lake City, SQL Saturday Utah - (Pending Approval)

Want me to come speak in your area? Just drop me a line!
tom@codesmithtools.com

See you on the road,
Tom

Friday, June 24, 2011

Dallas TechFest 2011 Registration is OPEN

Are you a developer? Do you live in the DFW area? Then come join me at...

Dallas TechFest 2011
When: Friday, August 12, 2011 - Saturday, August 13, 2011
Where: University of Texas at Dallas (Richardson, TX)

Use discount code TwoDays to get $50 (that's half) off the price of a ticket!

See you there,
Tom

Friday, June 3, 2011

Life is good in Florida

It seems that no matter what state I go to I find myself being pleasantly surprised.

Arkansas was fun, Iowa was cool, and now Florida is very chill. Perhaps I am thinking about this all wrong; maybe it's less about geographic or geopolitical lines and more about people. All these speaking tours I am going on have one thing in common: no matter where I go I am always surrounded by my fellow .NET developers.

...and all of you people rock!

I am a nerdy guy, and birds of a feather flock together, but this is more than that. Every user group has been filled with fun and interesting people, and we all arrived at the same destination by taking different paths. We come together at these meetings because we all "get it", we love what we do, and I can not think of a better crowd of people that I want to spend my time with.

In short: Thank you.

Thank you Microsoft for developing such great technology. Thank you INETA for helping these DNUGs stay organized. Thank you everyone that has come out to my presentations so far. Thank you everyone who has gone out after the meetings to keep talking shop. On that note:


A tavern that serves beer in pink elephant glasses...can anyone top that? I don't know, but I intend to find out with my remaining presentations!

  • June 7th (Tuesday) - Deerfield Beach, Florida - Code Generation
  • June 8th (Wednesday) - Fort Walton Beach, Florida - Code Generation
  • June 9th (Thursday) - Mobile, Alabama - Code Generation

See you out there,

Tom DuPont
Vagabond Programmer

Friday, May 13, 2011

LINQ to SQL vs Entity Framework vs NHibernate

I am working on a new presentation that is essentially a compare and contrast analysis of the three major ORMs out there (LINQ to SQL, Entity Framework, and NHibernate). My problem is not the content, it's choosing a name for the presentation! Here are just a few ideas that I've been considering:

  • Ultimate Fighter
    • Ultimate Fighter: ORM Edition!
    • ORM Showdown: The good, the bad, and the query.
    • ORM Fight Night
    • Object Relational Matchup
  • Misc Movies
    • ORM Club: If it's your first night, your app has to fight.
    • Super-ORM-Man 4: The Quest for Business Logic
    • Dr. Strange DAL: Or how I learned to stop worrying and generated an ORM!
  • Video Games
    • World of ORM Craft
    • pORMtal: This is a triumph!
    • pORMtal 2: Wa are going to have fun, with computer science!
  • Star Wars
    • ORM Wars, Episode 4: A New DAL
    • ORM Wars, Episode 5: The Profiler Strikes Back
    • ORM Wars, Episode 6: Return of the DAL
  • Indiana Jones
    • ORM and the Raiders of the lost DAL
    • ORM and the DAL of Doom
    • ORM and the Last Cascade
  • Star Trek
    • ORM Trek 1: The Data Access Layer
    • ORM Trek 2: The Wrath of DAL
    • ORM Trek 3: The Search for Business Logic
    • ORM Trek 4: The Request's Roundtrip Voyage Home
    • ORM Trek 5: The Data Access Frontier 
    • ORM Trek 6: The Undiscovered Productivity
    • ORM Trek 7: Code Generations
    • ORM Trek 8: First Contract
    • ORM Trek 9: SQL Injection
    • ORM Trek 10: ADO.Nemesis
  • The Hobbit
    • Lord of the ORM: Fellowship of the Data Layers
    • Lord of the ORMs: The Batch Queries
    • Lord of the ORMs: Return of the DAL
    • There and Back Again: An Entity's Tale, by ORM

Wednesday, May 4, 2011

PLINQO for NHibernate, Beta 1 Released!

PLINQO makes NHibernate "so easy, even a caveman can do it."

PLINQO can generated your HBM files, entity classes, and all NHibernate configuration in seconds. It then allows you to safely regenerate that code at anytime, thus synchronizing your mappings with the database while still intelligently preserving custom changes. PLINQO for NHibernate is a enhance and simplify wrapping of NHibernate that brings the best practices, optimizations, and convenience of the PLINQO frameworks to NHibernate.

Check it out, ya'll! Check it check it out!

Real Time Web Analytics