Rolling a Custom CMS System with ASP.NET MVC

The Beginning

When the bet365 Games product was first launched we decided to utilise a Content Management System, so that promotions, games and other content could be updated without developers having to make code changes and do releases. This put control of the website content into the hands of the business teams.

With such a rich selection of Content Management Systems available, you might wonder why a company would opt to create a bespoke one, but this is exactly what bet365 did. Many off-the-shelf systems are available, such as:

  • WordPress – offers a large selection of plugins & themes.
  • Drupal – offers rich control of content types and a lot of flexibility.
  • Orchard – same rich control and flexibility as Drupal but built on the Microsoft technology stack.

A custom CMS system simply makes sense when serving such a large and diverse audience, taking into account different regulated markets, and the speed at which bet365 want to add new features to improve the customer experience. Any off-the-shelf CMS would require extreme modification to the point that it would no longer be recognisable, and this kind of “shoe-horning” would lead to a hard to maintain code base with a high defect count.

Therefore, when we launched our Games site a custom CMS was created. An ASP.NET Web Forms system was built which sat upon a relatively simple database, allowing custom controls to be added and arranged in a tree structure. This allowed content to be extended and overridden for the different countries and languages that bet365 offered its product to. User Controls in Web Forms acted as the CMS controls and the layout and structure of these were defined by the data. The flexibility of this approach has proved useful, and it has reliably lasted for many years.

Image1

Why ASP.NET MVC?

With the growth of other Gaming the products, and the list of new features required, it became important to speed up the development, reliability and route to live progression time. The Web Forms system suffered from a lot of coupling between components, god classes and was becoming hard to maintain. It was decided that the best solution was to go through a refactor of the code into loosely coupled unit-tested components. This was to ensure:

  • A change in one area wouldn’t have knock-on effects elsewhere.
  • Easy to read and understand.
  • Easy to upgrade and extend for new features.
  • Each component documented by its tests.
  • Easy for new developers to get up to speed.

Although Web Form technology is perfectly suited to Rapid Application Development, where initial speed of development is key, ASP.NET MVC was deemed a viable alternative. This was due to its good separation of concerns between its components to allow unit testing throughout. ASP.NET MVC also offers much more precise control over the output of the website. This would remove some of the “bloat” that Web Forms required but wasn’t being used. This is key for the front end experience bet365 like to provide, as well as giving the performance required for such high traffic websites.

The Migration

Starting with the Vegas product, a move from ASP.NET Web Forms to ASP.NET MVC was planned. This product was green field and therefore was the ideal product to begin with. Considering the MVC system was going to be written from scratch, it was decided to write this in C# instead of the VB.NET used throughout the old system. Moving to C# was a team goal, being preferred by many developers as easier to read and more in use by the community.

The CMS is a mature system holding a lot of data, therefore it was obvious from the start that the data layer and tooling needed to remain in place to reduce impact and keep development time as short as possible. This meant that the MVC system needed to sit on top of data and code that was written specifically for a Web Forms website. The legacy system and proposed solution to deal with this was as follows:

Image2

The fundamental solution to the new MVC system was a high usage of the Adapter and Dependency Injection patterns, along with usage of HTML Helpers for recursively rendering children.

Adapter Pattern

This was used for adapting the content data into rich models that could be bound to partial Razor views to produce the output. A library of models and partials was planned to replace the traditional User Controls, with all the logic living in these adapters.

Dependency Injection Pattern

All new layers in the system were designed behind interfaces, and then interface injection was used to take dependencies where they were required. This ensured that no class was directly dependant on a specific implementation, only its public designed interface. Each interface was designed with only the bare essentials exposed to satisfy the requirement.

Castle Windsor was chosen as the Inversion of Control container to manage the dependency injection. The deciding factor was due to its rich set of features and how mature it was when compared to the other containers on offer at the time.

Testing

By utilising this method of Adapters and clean interfaces, unit tests were written for each level to ensure each Adapter, Controller and View performed as expected. NUnit and Moq were used for the testing, with Razor Generator used for testing the Razor views.

NUnit was picked over alternatives, such as MSTest, because it offered a huge amount of features and a lot more freedom and power in how tests can be written. Moq was used because it had a clean API when compared to others, such as Rhino Mocks.

HTML Helpers

A large library of available controls through the legacy system had to be recreated in MVC to allow the same flexibility of control. This also allowed arranging controls in dynamic tree structures and so each control had to be able to support children of differing control types. HTML Helpers were employed to perform the data-driven controller requests to hand off control of each content control to its associated controller.

The Next Level

When the bet365 Games website was redesigned, the new design demanded a better front end experience for customers and, crucially, a single responsive design to give the expanding mobile customer base a better experience. As part of this re-design, the site was to be migrated onto the, now proven off, MVC system. This seemed the perfect time to upgrade the MVC system with new functionality that would help with the features that Games required, as well as make a richer more powerful system.

SASS

For managing CSS, SASS was integrated into the MVC system; this was something that the development team requested after previous re-design projects. SASS allows better organisation of the CSS, which is especially useful for a single responsive design. The complexity of the requirements for the site, which included a large number of supported browsers, also meant that CSS management was very important for keeping the defect count to a minimum.

TypeScript

TypeScript was chosen for the scripting of the site as this was a technology already in use in other teams and it simply made sense to build on that success. AngularJS was one of the frameworks investigated that could be adopted, but it didn’t fit with the requirements of the website and so a similar component driven design was used, with a bespoke Inversion of Control container built to manage these components. This meant the same principles used in the C# could be used in the TypeScript, very useful when the same developers are writing both.

The more complex front-end of Games would require a lot of TypeScript code, and it seemed obvious to learn from the success of testing done in the C# by using unit testing on the TypeScript. A few frameworks were investigated for this:

  • QUnit – mature but is difficult to maintain the tests and had no built in support for headless running.
  • Jasmine – built in support for headless running, easy to maintain and clean fluent interface.
  • Mocha – very young, but has also has built in support for headless running, easy to maintain and clean fluent interface.

From the three options Jasmine was picked based on it having headless running by default which was required for the Continuous Integration, as well as its clean interface and being a more mature framework than Mocha.

What’s Next?

There is work ongoing looking into improving the performance of the MVC CMS system. There are some areas which could be re-designed to reduce CPU time required in rendering a page, and initial proof of concepts look very positive. These improvements should have a direct positive impact on page load time for customers, and increase the amount of traffic the web server can handle to better deal with peaks.

There are also investigations ongoing into MVC 6 (and ASP.NET Core), what benefits it can offer and when an upgrade should be considered.

With the growth of bet365, the Gaming team is growing as well, and effort is being put into a more decentralised architecture to allow splitting work out across distributed groups of people. The changes made for this will have an impact on how the MVC system grows with time.