ASP.NET MVC3 Tools Update – Scaffolding with the Repository Pattern

Today Microsoft released a new add-on for ASP.NET MVC 3. The ASP.NET MVC3 Tools Update does not update any of the dll’s used by an mvc3 project, but adds some great new tooling support. You can read more about in on Phil Haack’s Blog Post regarding this release.

In this post I’m going to show you how to use MvcScaffolding to add a new controller template to enable scaffolding with data access code that uses the Repository Pattern.

One of the new features is built in tooling support for scaffolding. The “Add Controller” Dialog box has been revamped to include a few new options.

 

New Add Controller Tooling

New Add Controller Tooling

 

As you can see there are much more options as compared to before. The scaffolding options are as follows:

  • Template: Allow you to specificy what kind of controller you want to generate. Out of the box you get an empty controller (Just a class with no actions), Controller with actions and views using the Entity Framework code first, and controller with empty read/write actions.
  • Model: This is the object that will be used for scaffolding strongly typed views, CRUD actions and data access.
  • DataContext: By default this is an EF Code First class that inherits from DbContext. You can either select an existing context or have the scaffolding tools create a new one for you.
  • Views: Select between ASPX and Razor. This is pretty much the same as the “Add New View” dialog box.
  • Advanced Options include layout/master page settings and View script settings. Again, stuff that is also in the “Add New View” Dialog.
Add new Controller Templates

Controller Templates

Scaffolding using the “Controller with read/write actions and views, using Entity Framework” is especially cool because it generates a controller, all associated views AND data access code for you. That’s right, all you need to do is create an model class and the scaffolder does the rest. How’s that for a productivity boost? 🙂

To test this I created a simple Product class which is defined as the following:

public class Product{
public int ProductId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}

Then I added a new controller with the following options:

Add Controller Product

Product Controller Scaffolding Options

The new tooling support created a new controller, all associated views and the data access code. That’s really cool, but let’s take a look at the controller code.

private ProductContext db = new ProductContext();
 //
// GET: /Product/
 public ViewResult Index()
{
return View(db.Products.ToList());
}

By default the scaffolding tools use the ProductContext object directly in the Controller. Many people don’t like this coupling (myself included) and prefer to use the Repository Pattern. This allows us to abstract away our data access code behind a repository, making it easier to work with and later modify, if need be.

Well the good news is that the add controller dialog is extensible. You can add your own controller templates to enable data access using any technology mechanism you want.

I’m going to show you a way to get a repository option for EntityFramework to show up with very little work. All you need to do is install the MvcScaffolding NuGet Package.

Open the Package Manager Console and enter “Install-Package MvcScaffolding”:
Install MvcScaffolding

Now right click on the controllers folder and select “Add”->”Controller”. We’re going to re-scaffold out our ProductController, associated views and data access code (WARNING: This will overwrite any changes you have made so be careful.)

Now take a look at the templates section and you should see new templates:

MvcScaffolding : Controller using repositories

MvcScaffolding : Controller using repositories

The last option let’s you scaffold out the entire thing and use repositories for data access. Go ahead and click “Add”. Check the checkboxes to allow the scaffolder to override existing items.

We can verify this by looking at our ProductController and we should see the following:

private readonly IProductRepository productRepository;

// If you are using Dependency Injection, you can delete the following constructor
public ProductController() : this(new ProductRepository()) { }
 public ProductController(IProductRepository productRepository) {
this.productRepository = productRepository;
}

//
// GET: /Product/
 public ViewResult Index(){
return View(productRepository.All);
}

Now the controller uses a repository instead of hard coding in the data access code. The repository itself uses EF Code First to do all the data access.

Advertisements