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!

Final Fantasy VI, Remake or Reboot?

This little rant is extremely off topic for this blog, and was inspired by a random conversation I had recently. Please note that reading about game design is small hobby of mine, and that these days I spend more time reading about video games than I do playing them.

Square Enix's Impending Demise

With Square Enix's stock in the toilet, and no major releases on the horizon, we are left with one delightful prospect to think about: Who is going to buy up their intellectual property, and what are they going to do with it? Yes, I am definitely getting ahead of myself. Square Enix is not gone yet, and the current trends seem to indicate that they will probably remake FFVI for the 3DS in the not too distant future. But hey, a guy can dream!

Personally I am delighted to see the JRPG juggernaut failing, specifically because I can't wait to see what gems will surface when they are forced to liquidate their basement. Square Enix has released, with very few exceptions, no new content since there big merge in 2003. What content they have released has been almost exclusively low rated rehashes of their old IP. They have been ridiculed for their lack of innovation, and reliance on merely porting and re-releasing old titles for revenue.

We have seen this same problem of stagnation appear in other mediums such as film and television, and the American film industry seems to have come up with a particularly effective solution...

Reboot The Franchise

It worked for Batman, James Bond, Star Trek, Battlestar Galactica, and many more. So why not put this technique to work in the video game industry?

As any artistic medium ages it also matures, and future generations continuously get held to higher standards. This is true for all aspects of every genre. I don't care if you talking about television (such as Battlestar Galactica), or film (Batman), every aspect of the new product is an improvement over the old: The plot no longer relies on deus ex machina. The scripts are held to a higher literary standard. Characters are deeper, multidimensional people who exhibit growth. The graphics, well I doubt that category this requires an example. 

Generally a reboot is called for once the old material has either gotten stale, or become trapped under its own overly contrived plot. Take for example, the X-Men movie franchise. As of movie three, it's box office and critical ratings had dropped, half of the main cast was dead, and thus it was no surprise that movie four tanked as well. Movie four, and any subsequent sequels, would inevitably be forced to carry around the baggage of the previous installments. The solution, reboot a prequel! Enter First Class, up go the ratings, out go the viewer's previously lowered expectations, and in comes that much needed revenue.

I am just filled with optimism about what a good reboot could offer the Final Fantasy franchise, specifically when working with such great content as FFVI, but I'll get there in a moment.

The Problem with Ports

I love Chrono Trigger. I bought it, played it, and beat it back on the SNES. Then I didn't buy it again, play it again, and beat it again back on the PSX. I did buy it again, play it again, and beat it again back on the DS. Now I am expected to buy it again, play it again, and beat it again on the Wii Virtual Console.

How many times am I expected to pay for the same exact content? I can sort of justify paying for the same content on a different medium, such as taking CT on the go with my DS, but I simply cannot justify paying for it on the same medium. Usually with DVDs or Blue Rays we are getting a higher quality format of the content, and even then I don't like paying for the same movie again. So why would I want to pay for the same low resolution sprites on my same TV in front of my same couch every 5 years?

While porting games can help bring games to the attention of new markets, and perhaps even help raise exposure for missed opportunities and cult classics, generally I view porting games simply as a means to grab some extra cash from successes gone by.

Example: Star Wars. Star Wars Digitally Remastered. Star Wars Special Edition. And soon, Star Wars 3D. Enough said.

The Problem with Remakes

So what is wrong with just remaking a classic, like they did with Final Fantasy IV for the Nintendo DS? Good question. I'll start by saying that FFIV DS was a good game, and finish by saying that it was simply nothing new. That's it, that's my entire critique of FFIV. Did you like the original? Then you will like the remake.

Here are some problems with remakes.

1) They don't solve the problems of the original game.
I love FFVI, it is hands down my favorite RPG of all time. However it does have flaws, and I am not just talking about the original mediocre English translation. Simple example: the entire second half of the game has a mediocre script because the game engine could not rely on you having certain characters in your party, and naturally there was a lot of miss opportunity there.

2) Remakes do not introduce anything new to the gaming experience.
We already know the plot twists. We already know all of the characters fates. We already know which abilities we will get, what they do, and which ones we will use. Even I will occasionally reread the same book, but it does not make me excited and willing to pay money when it comes out with a new forward and covert art. The same can be said for the Blue Ray format of a movie.

3) It causes what I refer to as Han Shot First Syndrome.
The primary goal of a remake is to up the graphics, this goes for both movies and games. However even when that is all that you try to tweak, you will still inevitably piss off your some percent of your fan base. Perhaps they will prefer the old designs, or more than likely some details will be lost or changed in a way that they don't like. The point is that you are not giving them something new to care about, you are giving them something different to bitch about. (On a side note: Han did shoot first, and it was those small details that made his character development so much better.)

The Potential of Reboots

A reboot is free to take the best of the original and ditch the pieces that just didn't work. It gives all of us something new while still preserving the nostalgia of the original. It is just as good for developers as it is for consumers. It is the very definition of win-win!

Look at a reboot as the ultimate application of user feedback. Not only can we review the initial user reactions, but also we have the opportunity to see how those impressions help up over time. With a reboot we are free to take into account years user input, and compare that data against both the past and the future iterations of the genre in question. A reboot basically turns the original experience into a really long beta, and provides us with a richer and more complete final product.

Also, with a reboot there can be no complaint that you are not getting your money's worth. Developers are making something new, and consumers are paying for something new.

Rebooting Final Fantasy VI

FFVI has so much great material to work with. A very large, equally diverse, well developed cast of characters. An epic plot spanning multiple generations and multiple worlds. An excellent plot with both humorous highs and literally world shattering lows. Shadowy figures, political intrigue, lies, betrayal, steam punk technology, summoning magic. I mean really, this game has everything!

So what could we make better?

1) The graphics.
Let's just get that one out of the way first. The game was beautiful back in 1994 and it has aged well, but so has Elizabeth Hurley and she is almost 50. Yes, it's time for this game to get a fresh coat of paint, but I want to see more. I want to see different costumes for our heroes in the world of ruin, such as Edgar's bandit leader outfit. I want to see Kefka actually fight the Espers in Thamasa, instead of him pointing his little hand at the sky. I want to see Terra morph into a radiating entity, not a light purplish thing.

2) The script, and the second half of the core story.
I alluded to this earlier, but the second half of FFVI has some technical flaws. While I love that the second half is completely open ended, and even completely optional, the limited game mechanics of that era left us with a somewhat incomplete final chapter. I want those world of ruin plot sequences to be as full and rich as the world of balance. Also the whole script could use an overhaul, and I don't just mean another re-translation. Go watch an episode of TV Drama from 1994, then watch one from 2011, that's the kind of difference I am talking about.

3) Additional sub-plots and side stories.
The Espers in particular should be flushed out more. FFVI does a wonderful job of turning their summons not only into key elements of the plot, but also into real characters. What it doesn't do so good a job of is flushing those characters out and taking the time to give them dialog. They all have names and powers, but why stop there? Why not give the Espers their own back stories and plot threads?

4) Character balance.
It's no secret that everyone loves the Figaro twins. Not only do they have great personalities and a cool story line, but they also have great combat abilities. I honestly don't know anyone who likes playing as Setzer, Relm, Strago, or Mog. We should take the time to fix that. Let's give Relm the art style controls of Okami. Let's give Mog some motion controls. Let's make every character as fun to play as Sabin's Streetfighter style Blitz controls.

5) Production value.
If you are going to reboot this classic, then there needs to be a significant investment put into it. The sound track was great for a synthesizer, but it needs to get remixed and played but a full scale orchestra. The script was classic but it was translated by a small time American sweat shop, we need to call in full time writers on both the Japanese and American sides. FFVI was one of the first turn based RPGs to have multiplayer, let's take it online and make the Coliseum a head to head challenge.

To me, Edgar will always be a "son of submariner", but Kefka doesn't have to say it again next time.

Avoiding Pitfalls

Any FFVI remake or reboot should be very careful not to fall in to the pitfalls of the modern Final Fantasy franchise. Assuming that Square Enix does end up remaking FFVI for the 3DS, I really hope they take these points into consideration.

1) Games are supposed to be fun.
Players want to go on an adventure and enjoy themselves, not train for a marathon. FFVI had great pacing. The game moved from event to event, and very rarely required you to grind for levels or money. The combat was both fast and fun. The camera never wasted my time spinning around at the start of every fight, and every action was almost a special ability instead of a boring old attack. The point here is that FFVI did all these things well, and it would be a shame for such features to get lost.

2) Go easy on the drama.
Good story telling defines itself by the contrast between its highs and lows. For every moment of sorrow there should be a moment of joy, characters need to laugh just as much as they cry. It is these different situations that help flush out characters, giving them depth. Final Fantasy plots always involve saving the entire world, they are epics, but it's still fantasy and should try not to take itself too seriously. Also, emo kids coming of age is a really worn out plot device. It is realistic for characters to doubt themselves, but it's really frustrating when it is a central plot point. 

3) Avoid the absurdism art style.
Vests and skirts are not battle armor. Airships should probably look like they can fly. Every summon does not need to split open the planet's crust. It is great for a game to be stylized, and a fantasy setting deserves to enjoy a lot of freedom in that department, but let's not abuse that privilege.

What do YOU think?

Should someone, preferably not Square Enix, reboot Final Fantasy VI?
Are there any other improvements that you would like to see?
What modern console would you want this for?
How soon could this happen?
Are you with me?
Kupo?

~Tom

Tuesday, July 12, 2011

Guide to Visiting Dallas

Some of my family is coming in to Dallas just to see the city, so they asked me for some help with planning their visit. After putting together some links for them, a thought occured to me: a lot of people are coming to Dallas for TechFest next month, and this might be able to help them out. 

I hope some folks out there find that useful!

Enjoy,
Tom

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

Real Time Web Analytics