A few days ago I've finally decided to spend some time with Microsoft's new ASP.NET MVC framework. Like all MVC implementations, the ASP.NET MVC framework provides a structured model that enforces a clear separation of concerns within applications, and makes it easier to unit test your code. It also helps provide more control over the URLs you publish in your applications, and can optionally provide more control over the HTML that is emitted from them. Here is a nice article on the history of MVC pattern.
ASP.NET MVC is in a pre-beta stage, but it is quite stable and there are even production sites running on it. For example, one of my recently favorites stackoverflow.com, a great resource of programming knowledge, is running on ASP.NET MVC. (it is amazing how programmers working on different technologies/stacks can behave together and share the knowledge.)
Update: ASP.NET MVC is now officially in Beta. As usual, to get all the details, check out the latest epic installment on ScottGu’s blog.
The other new technology I wanted to play with is LINQ. A fast description of LINQ from Wikipedia: "LINQ defines a set of query operators that can be used to query, project and filter data in arrays, enumerable classes, XML, relational database, and third party data sources. While it allows any data source to be queried, it requires that the data be encapsulated as objects. So, if the data source does not natively store data as objects, the data must be mapped to the object domain. Queries written using the query operators are executed either by the LINQ query processing engine or, via an extension mechanism, handed over to LINQ providers which either implement a separate query processing engine or translate to a different format to be executed on a separate data store (such as on a database server as SQL queries). The results of a query are returned as a collection of in-memory objects that can be enumerated."
And finally, after months working with some old, heavy "spaghetti-code" PHP applications (pre-version 5) I wanted to enforce a design pattern when designing my classes. Specifically, I've decided to implement the Repository Pattern.
The Repository Pattern is a very popular way to abstract a domain model from the underlying data mapping and data access by providing access to domain objects (business objects) via a collection interface. For example, the business objects can form collections under a single repository object such as:
- Repository.Managers, etc.
So, let's go!
Note: all the code listings below are written in C#, but i'm pretty sure the programmers will get the idea
First, we need to created the ASP.NET MVC project in Visual Studio. VS automatically is creating the project structure, folders, etc. , plus a test project where we can store the unit tests.
For this sample I have a simple table called "Projects". You can see the structure of the table below:
To create the LINQ classes, we need to add a new "LINQ to SQL classes" item to the Model folder, and then simply drag the "Projects" table to the Object Relational Designer designer. Visual Studio will take care and generate the classes. Additionally, you can drag stored procedures (if any). Later, you can access the stored procedures as methods of the respective LINQ class.
Ok, we have the MVC project, a table and the LINQ classes already. We need to access the data and pass it the views. We can access the LINQ classes directly from our controllers. For example:
Index() action above uses a LINQ to SQL
DataContext class to represent the database. The
DataContext class was generated by the Visual Studio Object Relational Designer.
A LINQ query is performed against the
DataContext to retrieve all of the projects from the Projects database table. The list of projects is assigned to a local variable named
allProjects. Finally, the list of projects is passed to the view through view data.
Working directly with LINQ to SQL in a controller class is perfectly fine in terms of MVC. However, it can create problems when you need to build a more complex application. It makes it difficult to switch data access technologies in the future. For example, you might decide to switch from using LINQ to using the Entity Framework, or strongly typed datasets, or whatever you like as your data access technology. In that case, you would need to rewrite every controller that accesses the database within your application. In addition, using LINQ to SQL within a controller class makes it difficult to build unit tests for your application.
The Repository Pattern
In order to build an MVC application that is more adaptable to future change and that can be more easily tested, we can use the Repository pattern. When you use the Repository pattern, you create a separate repository class that contains all of your database access logic.
When we create the repository class, we create an interface that represents all of the methods used by the repository class. Within the controllers, we write our code against the interface instead of the repository. That way, we can implement the repository using different data access technologies in the future.
The interface below is named
IProjectRepository and it represents a single method named
And the repository class below implements the
IProjectRepository interface. Notice that it contains a method named
ListAll() that corresponds to the method required by the
Finally, we need to change the
HomeController class to use the repository instead of using LINQ to SQL classes directly.
Notice that the
HomeController class has two constructors. The first constructor (the parameterless one) is called when your application is running. This constructor creates an instance of the
ProjectRepository class and passes it to the second constructor. The second constructor has a single parameter: an
IProjectRepository parameter. This constructor simply assigns the value of the parameter to a class-level field named
_repository. This is an implementation of a software design pattern called the Dependency Injection pattern. In particular, Constructor Dependency Injection.
Notice that all of the code in the
HomeController class (with the exception of the first constructor) interacts with the
IProjectRepository interface instead of the actual
ProjectRepository class. The code interacts with an abstract interface instead of a concrete implementation of the interface.
If you want to modify the data access technology used by the application then you can simply implement the
IProjectRepository interface with a class that uses the alternative database access technology. For example, you could create an
MySqlProjectRepository class or an
EntityFrameworkRepository class. Because the controller class is programmed against the interface, you can pass a new implementation of
IProjectRepository to the controller class and the class would continue to work.
Furthermore, if you want to test the
ProjectController class, then you can pass a fake project repository class to the
HomeController. You can implement the
IProjectRepository class with a class that does not actually access the database but contains all of the required methods of the
IProjectRepository interface. That way, you can unit test the
HomeController class without actually accessing a real database.
Nice and simple!
PS. Of course, you can implement as much repository methods as you need. For example (and to show some more LINQ magic) we can implement GetById() method in the
ProjectRepository class as follows:
and access it in our controller with something like
var myProject = _repository.GetById(5);