Single Page Application using MVC, Web API & knockout
This is the first post in a series about Tikal’s fuse day session “Building Single Page Application with knockout and ASP.NET MVC 4”. If you have already installed the new MVC 4 you can see there is a template solution called “SPA” (Single Page Application). This SPA application is used with conjunction of Web API (new to MVC 4) and on top of upshot.JS, knockout and nav.js. upshot.JS is a new micro framework from Microsoft that ease the interpretation between C# and JS, and since I wanted to stick to current open source technologies and maybe later not relay on a windows server (and IIS for that matter) I decided to do it with just knockout. I already talked about knockout and why it’s my preferred binding solution.
What I’m going to explain here is the basic architecture for the application. The solution is composed of 4 projects. I’ll walk through each of them from the simplest to the real deal.
The first project ReleaseIt is called after our demo company, and is the root for all the common functionality and tools we are going to use. For that matter it’s the same as System.dll assembly. And if we want to write helpers for XML serialization, will place them under ReleaseIt.Xml.Serialization. If the serialization folder will become too large, we’ll then split the folder into a new assembly called ReleaseIt.XML. So far the regular stuff, but just to make the things super clear I’m going over the basics here again.
The second project ReleaseIt.Web. Since we are writing a web application we’ll put all the web helpers in this assembly, just like the ReleaseIt assembly for general (system) stuff, here we’ll locate the web classes sticking to the same convention. In this assembly we’ll have the MVC folder for MVC extensions.
And in our case, the extensions to wire up the bundling in our application. So whenever we are in debug mode we want our JS files to be exactly as we wrote them: a separate file for each module or component that when put together – builds our entire application. But we still want them as separate files so it will be easy to debug when using the browsers developer tools. On release we want the opposite. We want all the files to bundle into a single file and go over minification process. In that way the browser will only execute 1 request for our entire JS app, instead of multiple requests for each JS module.
Now this is a philosophy of decision making. You can decide if you want to load your entire application as a single file when the user starts the application (much like Gmail), or load only the necessary files and later load asynchronously the rest of the needed files (like twitter is doing now).
There is one more important issue when bundling all your JS file: the order in which they are bundle. This can be a tricky situation if one module is dependent on others. The common solution is to use the CommonJS modules approach. The basics of this approach is that each module declares what are the other modules it depends on, and later a tool like require.js can be used to make sure a particular module requirements are fully fulfilled.
In our case the situation is very simple so we only iterated between the JS files and concatenated them into a single file. Much like the approach seen on this blog for CSS.
The third and fourth projects are basically the DAL implemented with a repository pattern: ReleaseIt.Repository is where all our interfaces and entities lie (much like a contract DLL in WCF), while the other project ReleaseIt.Repository.EF is the EntityFramework implementation of these contracts.
The hard wiring is done via MEF. It just was the simplest DI container for this job. So our DataProviders in the EF implementation declares an export
what we should have done is to register our DI container with MVC, or use MVC service locator. But then again, this was faster.
The main project
The main project is really just a regular MVC project with a few manipulations. I’ll go over each folder and explain:
- Content – the CSS, media and stuff
- Controllers – the MVC controllers. Here we only have 1 controller to serve our only page in the application.
- Underneath it we have an API folder for all our Web API. Each controller will inherit from ApiController and use MEF to get the proper provider
If you are not familiar with MEF or DI or Ioc, I suggest you read about these supper cools approaches. In most cases, because our DLL’s don’t have references to each other cause we are using MEF, the compilation time will reduce in half + we get loosely coupled components.
- The Scripts folder is where all our JS Script are (I used NuGet for all the scripts packages) like JQuery and alike.
- JS folder is where our application located. We have controllers and viewModels that serve each view in the application. All our modules are implement with the module design pattern
- The Views folder is the basic MVC views folder. I stripped it out of most of its content, since we only have 1 page in the application (Index.cshtml). The other file in the folder is _ViewStart.cshtml which is the code that executes before every view is rendered.
Under the Shared folder we still have our _Layout.cshtml (the master page) and others alike (footer & header). By the way the convention for _XXX (underscore) is for partial views in MVC.
- Underneath the shared folder we have the Pagelayouts that we are going to use: each page can be composed of 1 or more templates. And of course the Templates folder for the, well, templates.
Well, that’s basically it; you can catch the main drift. On the next post I’ll go over the views and JS to explain how we composed our application so keep tuned.