RSS

Adding a Lazy Loading Pattern to T4MVC

06 Apr

I added T4MVC to our ASP.NET MVC application yesterday. Great idea – don’t know why it’s taken me so long to get ’round to it? Unfortunately, a number of my unit tests were now failing with a System.NotImplementedException being thrown.

Some of our controllers are currently redundant so I changed the base class’ constructor to make sure no-one called them accidentally…

public abstract class MyRedundantBaseClass
{
  public MyRedundantBaseClass()
  {
    throw new NotImplementedException();
  }
}

Now, none of my tests go anywhere near this class (or any inherited ones) so why was it throwing the exceptions?

The problem is in one of the auto-generated classes in the T4MVC.cs file. The template generates a static field for each non-abstract controllers in your application…

public static class MVC
{
  public static MyApp.Controllers.Account.AccountController Account = new MyApp.Controllers.Account.T4MVC_AccountController();
  // Repeated for each controller...
}

This list of fields also included a number that extended my redundant class. So, as soon as I did anything with the T4MVC framework all these classes got automatically instantiated and now I’m dead in the water.

My solution is to edit the template so that it generates a Lazy Loading version of the T4MVC.cs file. This also makes it a little more efficient as it will only new-up classes when it needs them.

Here’s the old template section (starting from line 73)…

<#foreach (var controller in DefaultArea.GetControllers()) { #>
    public static <#=controller.FullClassName #> <#=controller.Name #> = new <#=controller.FullDerivedClassName #>();
<#} #>

… and here’s what I changed it to…

<#foreach (var controller in DefaultArea.GetControllers()) { #>
 private static <#=controller.FullClassName #> _<#=controller.Name #>;
<#} #>
<#foreach (var controller in DefaultArea.GetControllers()) { #>
 public static <#=controller.FullClassName #> <#=controller.Name #>
 {
  get
  {
   if (_<#=controller.Name #> == null)
     _<#=controller.Name #> = new <#=controller.FullDerivedClassName #>();
     
   return _<#=controller.Name #>;
  }
 }
<#} #>

This now generates the following code in T4MVC.cs…

public static class MVC
{
private static MyApp.Controllers.Account.AccountController _Account;
public static MyApp.Controllers.Account.AccountController Account
{
get
{
if (_Account == null)
_Account = new MyApp.Controllers.Account.T4MVC_AccountController();

return _Account;
}
}

// Repeated for each controller…
}
[/sourcecode}
I still need to add a double locking mechanism for thread safety, but I think this makes a valuable improvement to an already great framework.

Advertisements
 
1 Comment

Posted by on April 6, 2010 in ASP.Net MVC

 

Tags: ,

One response to “Adding a Lazy Loading Pattern to T4MVC

  1. David

    April 6, 2010 at 8:00 pm

    Good idea, let's get this change in. Let's discuss by email offline. Thanks!

     

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: