At the Open Force Europe conference in October I will be presenting a talk on Creating Testable Modules. In this series of blogs I will be describing my learning experiences as I work my way through creating the examples and presentation material for the talk.
Phil Beadle has created a Project Template that you can download from the Forge, and I encourage you to work with this template if you are interested in building testable modules.
This blog is cross-posted from my personal site. For those interested in viewing larger versions of the diagrams you can read the post there.
In the first part of this blog series on creating testable modules I described the need for supporting testability in DotNetNuke Modules. Lets take a look at our current typical N-tier design.
Figure 1 – Current Typical DotNetNuke Module Design Pattern
Figure 1 shows the current typical DotNetNuke Module Design Pattern. This is a fairly standard N-Tier design with 3 layers. The top – Presentation - Layer includes the User Control – both the ASCX file and the code behind file, the middle – Business - Layer includes the Controller class and the Info Class and the bottom – Data – Layer includes the Data Access logic.
The first problem with this design from a testability point of view is that it is not possible to isolate the Presentation Layer from the rest of the module, as User Controls don’t “exist” outside of the WebForm Framework. The Presentation Layer can be tested through the use of Web Automation Frameworks like Watin or WebAii but these, while useful are not Unit Tests in this scenario.
So we obviously need to modify our design pattern if we are going to Unit Test all aspects of our Module.
Model View Controller – MVC
The Model View Controller pattern has been around for some time, and was originally developed in Smalltalk to decouple the user interface from the internal application state and the business logic that manages that state.
Figure 2 – The MVC Design Pattern
There are three components: the Model, View, and Controller. The MVC pattern relies heavily on events so that the interface between the three components are not tightly coupled. In fact, only one object, the Model, is usually physically shared between the View and the Controller.
- Model - The Model maintains state information and manages state persistence. It generates events when state changes.
- View - The View displays state information. It monitors state change events and updates the user interface accordingly. It can query the Model for additional state information. The View does not change model state.
- Controller - The Controller responds to View events (User Requests), which in web applications are usually REST-friendly URLs. It contains the business logic determining how to change the Model state based on View events. It can also query the Model's state. The Controller usually changes Model state through direct calls to the Model.
The MVC pattern is a popular web application design pattern and is the basis for the Ruby on Rails framework. There are a couple of MVC Frameworks for .NET including the new ASP.NET MVC Framework being developed by the Microsoft ASP.NET team, and currently in Beta.
However, MVC does not fit well with DotNetNuke which is principally written using Web Forms and is firmly tied to the Postback model, where a user interacts directly with the View.
Model View Presenter – MVP
The Model View Presenter pattern solves the issue with the MVC pattern that DotNetNuke does not support direct interaction with the Controller. In the MVP pattern the user interacts with the View through the normal ASP.NET WebForm Postback model At the same time, this pattern also solves our problem with separating the responsibilities for view updating and event handling by using two separate classes.
Figure 3 – The MVP Design Patterns
|MVP – Passive View
||MVP – Supervising Controller
The MVP design pattern has two major variants, which differ by how much the View interacts directly with the Model.
In the Passive View variant, the View is updated exclusively by the Presenter, whereas in the Supervising Controller variation the View interacts directly with the Model to do simple data-binding that can be defined declaratively. In this variant, the Presenter still handles the more complicated updates. This variant allows for the the modern use of data-binding controls, but is not quite as testable as the Passive View variant.
This is a very brief introduction to the MVP Pattern. In the next blog I will show a simple example “Hello World meets MVP” of how the design pattern is used in practice.