We’ve been building out the site CurbstoneComment.com using MVC 4 and Code First Entity Framework 6 and it’s been delightful taking advantage of all the magic offered up via these whiz bang technologies that do so much useful work under the hood. As the site starts coming together, we don’t want to wait too long before starting to write some unit tests, since we’re such big believers in Test Driven Development (TDD). It is comforting to know that MVC promises to enable testability without requiring dependencies on a Web server, a database, or external classes.
In previous posts, we’ve set up the MVC project, deployed it on our web server (yes, it’s far from production-ready but we don’t have DEV and QA environments set up for these purposes), we’ve used EF to create our database model and provision our database, and we’ve used MVC Scaffolding to build our controller and repository classes. There have been several re-do’s and we’ve discovered that some EF functionality didn’t appear to work as advertised (but we worked around it), but overall this project has gone very smoothly with every little coding needed on our part.
Take a closer look at the ItemRepository class that MVC Scaffolding created. The main problem we’re going to face in creating unit tests for this code is separating the context object (of type CCContext) from the data layer. The context object opens and maintains the connection to the database, but we don’t want our unit tests to be dependent on any database.
The problem is that our unit test component is going to be dependent on the database connection in another component. A way to solve this problem is to ensure that we build a loosely-coupled set of software components so that high-level modules don’t depend on low-level modules. This can create headaches (DLL hell!) as our application gets more and more complicated.
Two design patterns can help with this:
The Dependency Inversion Principle provides guidelines to write loosely coupled classes.
The Inversion of Control is a mechanism with which we can make higher level modules depend only on abstractions, rather than concrete classes.
Together, these patterns are rolled into a big, popular design pattern called Dependency Injection. For a full discussion of DI, check out this article.
If you noted that our ItemRepository class implements an interface IItemRepository, you will begin to see how we are going to approach this.
In our Unit Test project, we will create an in-memory ItemRepository that also implements IItemRepository. We will write code that mocks the DBContext and also mocks the magic of MVC by creating a class that mocks the HttpContext. We will be invoking the MVC routing engine without using a web server!
We want to test the controller’s ability to select an Item from a list by the correct ItemId.
We create our test data, the repository manages it as if it were a live database, and the controller looks up the correct item and our test passes.
TDD is a widely accepted best practice these days in the software industry. Unit Tests have their limits and we will need to write Integration Tests as we get our application more complete and connect it with a database. Write those unit tests first and you will smile more later!
If you’re a software developer working on existing projects, you may not have many professional opportunities to use some of the latest whiz-bang tools and technologies that are out there. I am building out the www.CurbstoneComment.com web site, so I get to do green field development--build from scratch. I thought I’d take the “code first” approach to database design/development, letting entity framework build my database for me. I found this helpful article that takes the concept one step further by using MVC 4 Scaffolding to do the actual coding of my project’s Controller and View classes. I patterned my work after the steps it outlined.
Technologies Used Here:
Visual Studio 2010 with SP1
Entity Framework 6
Nuget Package manager for Visual Studio
Sql Server 2008
Before We Start
Code first is the process of designing and implementing a database by first creating Model classes that describe the database. Then Entity Framework 6 reads your classes and automatically generates the SQL Server database tables. You can read more here.
Entity Framework is an object-relational mapper that enables developers to work with relational data using domain-specific objects. What this means is developers don’t have to write by hand much of the code for database access. You can read more here.
MVC 4 is a framework for building web applications. Our web application for CurbstoneComment.com uses MVC 4. You can read about how we built our application up until this point here.
MVC Scaffolding is the newest and most obscure of these technologies. Scaffolding takes the auto-generation of code one step further and creates Controller and View classes based on the Model classes used to create the database.
We begin by installing MVC Scaffolding. This is a NuGet package installed via VS 2010’s Package Manager Console. For details on how to install these packages, read the first article referenced above here.
Then we build our Model classes, using decoration that will help Entity Framework build its database tables. The ItemModels.cs file will include classes for Item, ItemCollection, and CollectionType.
The magic happens when we issue the Scaffold Controller Item –Repository command within Package Manager Console. Scaffolding created views for my Item objects:
And Scaffolding created a controller class for our Item objects:
I just had to add links to my menu and the code was ready to run.
But my database tables aren’t created yet. The tables don’t get built until the application is run. This happens when the global.asax file’s Application_Start event fires and issues the command System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges());
The first time any user clicks on the Items link, there’s a short pause and there you go, your tables are created!
But beware: if you make any changes to your model, your database tables will be dropped and re-created, meaning all of your data is hosed. If I were using this in a production environment, I would want to make sure I understood all the circumstances that would kick off a rebuild of my database tables. It’s easy to see how this could be catastrophic for a running web site. It would be nice if EF creates a restore script before it wipes out your data.
I also noted a failure in one of my tables. I had tried to create a table ItemCollection that included a list of Ids back to individual Items. It simply ignored this field. It could have set up a link table with ItemCollectionIds and ItemIDs but I guess even Entity Framework 6 is not that smart.
Overall, these are powerful and time-saving tools for developers. I hope this helps someone!
I have spotted a number of posts and responses about how to deploy an MVC web application within an ASP.Net web site. I tried a number of solutions and always wound up with a “Could not load type MyAppName.MvcApplication” at build time for the web site or at run/compile time on the web server. The basic problem appears to that the MVC web application compiles into a namespace and a DLL while the ASP.Net web site “magically” knows what its namespace. Simply copying the MVC web application does not totally work, even if you try the steps outlined on these web sites:
Judging by the comments on these pages, I am missing something or doing something wrong. Indeed, several of the posts include responses from the original author that he missed something. I also suspected that part of my problem was the process of deploying to a real web server. I am using Visual Studio 2010, and all this may be easy to set up in 2013, but that’s the tool I’m working with today. Still, if there is a simpler way, I would like to find it. And I am also seeking a deeper understanding of how MVC works in the real world. So I forged ahead, spent a little time and I think I achieved both of my goals.
My solution is basically to create an ASP.Net web site, add an MVC application to the solution, add a reference to the MVC project to the web site, then copy some, but not all of the MVC application’s from the MVC app’s project over to the ASP.Net web site. The MVC application’s controllers will do their job, but content such as Views, images, and scripts will be served up from the ASP.Net web site’s project.
Create a new ASP.Net web site. In VS 2010, select File |New | New Web Site. Use the ASP.Net Empty Web Site template. The Web Location will be FTP and the path is ftp://ftp.mywebsite.com. (I removed the default path of /WebSite.)
Pretty basic. Empty, in fact.
Add an MVC 4 Web Application to the solution. Right click on your solution in Solution Explorer, and select Add | New Project and choose ASP.NET MVC 4 Web Application. I named mine CC.
And now you have the basic MVC 4 web app. Note that the MVC project builds and all the unit tests pass.
Now we will start moving essential files over from the MVC4 app to our web site.
In the web site, create a bin folder and add a reference to our MVC4 project. This will cause our DLL and all those DLLs required in the packages.config to be copied over to our web site’s bin folder. Just for fun, let’s see whether our site works yet.
We need to manually add some of the dependencies. VS2010 handled a bunch of them, but some are missing.
We will find them in our MVC4 project’s bin folder.
Right click on the web site bin folder and select Add Existing Item.
We are getting closer! The missing elements are the files that cause our MVC app to kick off.
Now we will copy the MVC4 folders and files we need on the web site. Copy these entire folders from the MVC4 project to the web site project:
Finally copy the Global.asax and Global.asax.cs files from the MVC4 project to the web site. It should look like this:
Note that, even without all the folders we cut from the MVC4 project, it still compiles and its unit tests still pass. How does the web site run?
There it is! The basic ASP.NET MVC template is up and running!
We just have a little clean-up to do, so we aren’t confused later. We still have duplicate Global.asax files, so let’s clean those up. In the web site, just delete Global.asax.cs file or comment everything out. In the MVC4 app, the Global.asax isn’t really needed anymore, but the code from the code-behind page is needed. I created a new class called StartUp.cs, pasted the code from Global.asax.cs as-is, then deleted both Global.asax and Global.asax.cs from the MVC4 app.
The MVC4 app still builds, unit tests still run, and the website still works. So what this demonstrates is how the MVC’s Models, Controllers still uses code compiled in the MVC4 DLL, while the Views and their Razor cshtml code reside on the web site. Is this the architecture that is ideal for our custom solution? Perhaps not, but not bad for an out-of-the box start.
Now the real fun begins of customizing the MVC4 code, altering the views and other content, hooking up data sources, etc, etc. I hope someone finds this useful.