A large part of life is about making choices. We make hundreds of decisions every day. Whether it is a mundane decision like what to eat for breakfast, or a life altering decision like whether to get married. For computer geeks like me it might be whether to use VB or C#, or whether to write my web app using Web Forms or MVC. Many of the choices we make in life are outward expressions of who we are. We often make choices not for any logical reason, but because of some emotional feeling that we have. Why does one developer prefer C# while another developer prefers Java?
As a development framework and platform, DNN has always catered to a broad development community. This is fundamentally what extensibility is all about – it is about allowing users to make their own choices. How do you architect the platform such that developers can swap out the default functionality with some alternate implementation? How do you give developers choices to use the framework and platform in a way that feels natural to them?
Background
Shortly after DNN was created as a VB project, the developer community started asking for a C# version of the platform. For many developers it was not a question of whether they could learn VB or whether VB was good enough for the job, it was just that many developers preferred C# for their day to day development. A large number of organizations began adopting C# as their standard language and this increased year over year. Eventually, it was obvious that by remaining a VB only solution, that DNN was unnecessarily limiting users and organizations who would adopt the platform.
In 2011 we made the decision to adopt C# as the official language for DNN Platform development. Fortunately, thanks to the .Net framework, all the great DNN extensions written in VB continued to work. This change allowed DNN to address the concerns of the growing C# audience while still providing support for the VB developer community.
In 2009, Microsoft released the ASP.Net MVC framework. The MVC framework was intended to provide additional options for .Net developers who wanted to use a more modern approach to web development. MVC provided improved testability, better control over the markup that was rendered, cleaner separation between presentation logic and business logic, and a faster rendering pipeline. Unfortunately, adopting MVC for a platform like DNN would have meant making drastic platform changes. Also, many developers were happy with ASP.Net Web Forms and didn't see much benefit to making a transition to MVC. This was one choice that we could not give to our developer community... until now.
Last summer Charles Nurse began doing some R&D on Project Maverick. The purpose of the project was to determine the feasibility for supporting MVC development on DNN without introducing massive breaking changes. The hope was that we could leverage the MVC framework for doing module development without requiring the entire platform to be rewritten in MVC. Project Maverick was a big success and Charles proved that not only was it feasible to create modules using MVC, but that it wouldn't require disruptive changes to the core platform. MVC and Web Forms could work seamlessly together, even on a single web page.
The fruits of the Project Maverick effort will finally be released with DNN 7.5 when we introduce a new MVC module type. We are working hard to make MVC modules a truly first class developer experience in DNN and will support pretty much the entire ASP.Net MVC framework. There are, however, a few exceptions like Routing and MVC Areas which don't make sense in the context of a DNN site.
Implementing MVC
The DNN MVC implementation tries to stay very close to ASP.Net MVC. If you have built an ASP.Net MVC app then you should feel right at home building DNN modules using MVC. Like many modern development frameworks, we have favored a convention over configuration approach. The conventions are built into the DNN framework but can be overridden if necessary. This approach reduces development friction while still allowing for customization.
Models
Building models for MVC modules doesn't require any special magic. In fact, you can continue using your favorite DNN data access techniques with your MVC modules. Your model is just an object that contains the data you want to display and it can be as simple or as complex as you like. Your model might be an existing DNN domain object like a UserInfo object or it might be some custom object that is specific to your module. There is no requirement to inherit from any base class or to implement any special interface. You just need an object – any type of object will suffice.
Views
ASP.Net MVC views are somewhat analogous to the User Controls that you use for building DNN modules today. Unlike User Controls, MVC views are just the presentation template with a small bit of embedded presentation logic. Out of the box DNN 7.5 will support the ASP.Net Razor view engine, although it wouldn't be too difficult to support other view engines in the future. DNN implements a small view base class (DnnWebViewPage<>) so that we can inject DNN specific context that you can use for accessing common elements like the ModuleID, Module Settings or Portal Settings. The base class also handles wiring up DNN specific HTML, URL and AJAX Helper classes. The DnnWebViewPage class is similar to inheriting from PortalModuleBase for your User Controls and should be a familiar concept to current DNN developers.
In order to provide a more seamless developer experience, we have overridden some of the standard helper classes in ASP.Net MVC so that we can provide DNN specific implementations. The DNN specific versions will use the same API signature but are designed to function in a DNN site. For example many of the URL helpers assume that ASP.Net routing is being used. Since DNN relies on our own URL rewriting, we needed to change how URLs are generated using these standard helpers. This approach will allow us to support the same functionality that ASP.Net MVC developers rely on, but in a very DNN friendly way.
NOTE: The ASP.Net URL and AJAX helpers are not complete in this CTP, but will be available in later nightly builds or the next DNN 7.5 CTP.
Controllers
ASP.Net MVC controllers are used to accept input from the users and then update or retrieve data from the model for presentation. Each controller defines one or more actions which are used for handling some user interaction in the module. Like views, controllers in the DNN implementation will inherit from a common base class. Not only do we add DNN specific context to the controller, but we also use this base class so that we can attach a custom ControllerActionInvoker to capture the output and inject it into the page.
Module Actions
The Module Action menu is a unique feature of DNN and doesn't have a corresponding analog in the ASP.Net MVC framework. Modules built using the Web Forms framework are able to implement an interface on the module controls which exposes custom module actions. Because of the differences between Web Forms and MVC frameworks we were not able to use this same approach. Instead we have created two custom method attributes (ModuleActionAttribute and ModuleActionItemsAttribute) that you can use to either create a single module action, or where you can identify a method that returns a ModuleActionCollection (the same basic method signature used for IActionable). These method attributes are used to decorate your individual Controller Actions where you need custom module actions. You can see an example of this in the sample code used on the simple MVC Html module.
Conclusion
It is still early in the DNN 7.5 development cycle and we have a long way to go until release this summer, but we are getting closer to wrapping up the core MVC development effort. If you are an ASP.Net MVC developer we hope you like this implementation. We think we have covered most of the mainline MVC features but would love to hear your feedback. If we missed some critical feature, or you find a bug with the implementation, we would love to hear from you. If you want to help on the development feel free to submit a pull request against the feature/8.0.0 branch.
We are beginning work on some sample MVC modules and some developer documentation with walkthroughs on the whole process of creating a module using MVC. The modules and documentation should be available in an upcoming DNN 7.5 CTP release.
You can play with the MVC bits today by downloading the DNN 8.0 source code from GitHub, downloading DNN 8.0 CTP 1. CTP 1 includes the core of the MVC development experience but is still missing some of the MVC helper methods.
NOTE: As part of this release we have increased the server requirements to ASP.Net 4.5. You will need to install this framework before installing this version of DNN.