Advanced Scaffolding

Chapter 4 overviewed the new scaffolding feature included in the ASP.NET MVC 3 Tools Update. This feature makes it easy to create the controller and views to support create, read, update, and delete functionality just by setting options in the Add Controller dialog. As noted in that chapter, this scaffolding system is extensible. This section will describe a few approaches for extending the default scaffolding experience.

Customizing T4 Code Templates

The default scaffolding provided by the MVC is powered by T4 templates (T4 is a code generation engine integrated with Visual Studio). Assuming your Visual Studio installed directory was C:Program Files (x86)Microsoft Visual Studio 10.0, you would find these templates in the following locations:

  • C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDEItemTemplatesCSharpWebMVC 3CodeTemplatesAddController
  • C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDEItemTemplatesCSharpWebMVC 3CodeTemplatesAddView

MVC first looks for a CodeTemplates folder in your project, so if you want to customize newly Controllers, you can copy the CodeTemplates folder directly into the root of your project and add your own T4 templates. Better yet, you can install the Mvc3CodeTemplatesCSharp NuGet package (or Mvc3CodeTemplatesVB for Visual Basic) into your project. This copies the templates into your project; it also sets the build action correctly for these files so Visual Studio doesn't try to run them when you open them.

Code Templates versus Helper Templates

Don't confuse these templates with the helper templates used within MVC views. The Editor and Display templates (discussed in the Templates section later in this chapter) are used to display model information within a view, while the T4 templates discussed in this section are used by Visual Studio when you are adding new code items to your project.

The MvcScaffolding NuGet Package

While the T4 approach in the previous section works, the scaffolding experience in ASP.NET MVC 3 is dramatically improved by the MvcScaffolding NuGet package.

UnFigure
Install-Package MvcScaffolding

This package, which is produced by the ASP.NET MVC team, adds several great scaffolding features:

  • It adds a few more advanced template options to the Add Controllers dialog
  • It allows you to really take command of the scaffolding experience using custom PowerShell commands from the Packager Manager Console
  • It automates the process of creating your own custom scaffolders
  • As it is a NuGet package, the team can publish more frequent updates (outside of the ASP.NET MVC release cycle), which you can apply via NuGet

For precisely that last reason, we're not going to document MvcScaffolding in great detail here — it would very likely be out of date by the time you read this. We'll give you an overview of how it works, and then point you towards web references so you can keep up with future updates.

Updated Add Controller Dialog Options

The MvcScaffolding package adds two new options to the Add Controller dialog, as shown in Figure 14.1.

  • MvcScaffolding: Controller with read/write actions and views, using EF data access code: This is very similar to the default Controller with read/write actions and views, using EF template. There are some minor improvements, such as the use of a common partial view for both create and update scenarios.
  • MvcScaffolding: Controller with read/write actions and views, using repositories: This is the more interesting template added by MvcScaffolding We'll look at that next.

Using the Repository Template

To use the repository template, add a new repository and select the MvcScaffolding: Controller with read/write actions and views, using repositories template as shown in Figure 14.2.

This example replaces the existing StoreManagerController in the MVC Music Store application with a new controller (and views). Instead of including Entity Framework data access code in the controller, as shown in the example in Chapter 4, this controller abstracts the data access code to a separate AlbumRepository class. The code for this class is shown as follows.

using System;using System.Collections.Generic;using System.Data;using System.Data.Entity;using System.Linq;using System.Linq.Expressions;using System.Web;namespace MvcMusicStore.Models{     public class AlbumRepository : IAlbumRepository    {        MusicStoreEntities context = new MusicStoreEntities();        public IQueryable<Album> All        {            get { return context.Albums; }        }        public IQueryable<Album> AllIncluding(             params Expression<Func<Album, object>>[] includeProperties)        {            IQueryable<Album> query = context.Albums;            foreach (var includeProperty in includeProperties) {                query = query.Include(includeProperty);            }            return query;        }        public Album Find(int id)        {            return context.Albums.Find(id);        }        public void InsertOrUpdate(Album album)        {            if (album.AlbumId == default(int)) {                // New entity                context.Albums.Add(album);            } else {                // Existing entity                context.Entry(album).State = EntityState.Modified;            }        }        public void Delete(int id)        {            var album = context.Albums.Find(id);            context.Albums.Remove(album);        }        public void Save()        {            context.SaveChanges();        }    }    public interface IAlbumRepository    {        IQueryable<Album> All { get; }        IQueryable<Album> AllIncluding(            params Expression<Func<Album, object>>[] includeProperties);        Album Find(int id);        void InsertOrUpdate(Album album);        void Delete(int id);        void Save();    }}

Separating the data access logic from the controller code provides a number of benefits. It's easier to test the controller code (as explained in more detail in Chapter 12, in the section titled Keep Business Logic out of Your Controllers). Additionally, it's now possible to reuse the repository code elsewhere in your project.

Adding Scaffolders

The MvcScaffolding system uses scaffolders to generate code. You can create your own scaffolders, and conveniently (but slightly funny in a mind-bending way) the easiest way to get started with the code for your custom scaffolders is to generate it — using CustomScaffolder, a scaffolder included in MvcScaffolding, of course.

Creating a new scaffolder to handle a new controller scenario, for instance, is as simple as typing the following in the package manager console:

Scaffold CustomScaffolder AwesomeController

This adds the required files for the AwesomeController scaffolder to a new folder in your project, CodeTemplatesScaffoldersAwesomeController. Of course it's up to you to edit the generated code for this scaffolder, but everything's set up for you so you can just focus on the code that makes your scaffolder unique.

Additional Resources

As promised, we've kept this discussion at a pretty high level because it's subject to change. The best source of information on MvcScaffolding at the time of this writing is found on Steven Sanderson's blog (as he is the primary author of MvcScaffolding): http://blog.stevensanderson.com/category/scaffolding/.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.115.155