About the author

My name is Ben Foster. I am a developer based in the UK. I particularly enjoy working with Microsoft .NET technologies. This blog is all about my journey as a developer and the things I learn along the way. Enjoy!

In this post I am going to cover how we can extend the widget system to support complex widgets that perform their own data binding using external services.

In this example I am going to create a widget that displays a specific project in our portfolio application. We will want to store the Id of the project to display in our widget properties but we also need a way of loading the project itself from our project service.

For details on the overall architecture of the Widget system please see the previous post. The points of interest are the ProjectWidgetViewModel (at the very bottom of the snippet) and the CreateDisplayModel method.

In this method we retrieve the project from our project service using the project id (or slug) stored in widget properties. Then we map the project to our model and set the DisplayModel property accordingly.

A key point is how we got a reference to our project service. This was actually injected for us using StructureMap. The bit of magic is in our WidgetService. When we retrieve a widget to be displayed, we check if it implements IWidgetWithDisplayModel and if so, call ObjectFactory.BuildUp on our widget to fulfil any dependencies using setter injection:

At the top of the view we are casting the dynamic DisplayModel property as a strongly typed ProjectViewModel object. We can do this because it’s a known type although there is nothing stopping you from just working with the dynamic model directly.

One area that I think ASP.NET Web Forms makes easier, is the ability to create self contained user interface components that contain all the logic necessary to load data, perform any required processing and produce an output.

ASP.NET MVC provides a greater separation of concerns resulting in applications that are easier to manage and test. So when it comes to creating a widget system we have to take a different perspective. Of course we could just load the data for our widget inline within our views, but then this would violate MVC principles that our controller is responsible for passing the Model to the View.

One feature of ASP.NET MVC that makes creating widget style interfaces possible is the RenderAction method. This allows us to call an action on a controller and render the response of that action within an existing page. However, in order to make our widget system dynamic, I don’t want to have to create a separate controller, routes etc. for every widget. The same applies to configuration. It would be better if we could have a generic configuration interface for all widgets.

So some high level requirements are:

Provide a single endpoint (controller action) for displaying widgets

Provide a generic way of configuring widgets

Find a way of creating complex widgets that can load their own data without violating MVC principles

Allow widgets to be dropped into our app as assemblies without requiring an additional configuration.

There are a few framework features and tool that I will be using to create the widget system:

As previously mentioned, RenderAction to display the plugin

Dynamic view models

MVC’s EditorFor template helper for widget configuration

Entity Framework Code First (although I’m likely going to switch to NH for reasons I will explain).

StructureMap to provide the “pluggable” aspects of the application and inject dependencies into our widgets.

The first thing I want to do is create an interface that each widget must implement. This defines some of the behaviours of a widget:

Properties: Most widgets instances are going to need to store information that will be used directly within the widget View (e.g. displaying some html content) or perhaps used to configure the widget (e.g. twitter user id for a twitter widget). Since we want to be able to add new widgets without changing our database, we need to create a simple key value pair store for such properties. We will use EF to wire up this association.

EditViewModel: This allows us to create a model containing all the properties we wish to be able to set for our widget instance, along with any validation rules. We can then make use of ASP.NET MVC’s EditorFor template helper and dynamic views to create a configuration interface that works for all widgets.

UpdateFromViewModel: Since each widget’s edit view model is likely to be different it makes sense to let the widget handle the updating of it’s properties from the view model. Once done, we can pass the updated widget instance to our repository so that all the changes are persisted.

Since the Entity Framework does not support mapping to interfaces (like NH) we have created an abstract Widget class that all widgets will inherit from. We will be using Table-Per-Hierarchy mapping (TBH) to map instances of this class to a Widgets table in our database. All custom widget properties will be stored inside the WidgetProperties table.

It is the TPH mapping that will allow us to add new widget types without requiring any database changes since EF will automatically add the top level widget properties to the existing Widget table along with a type discriminator.

I mentioned above that I will be moving away from EF to NHibernate. One of the reasons is the way in which EF auto maps properties. If I create a Twitter Widget with a writable property “UserId” and try and save this widget, EF will expect to persist this to a TwitterWidget table. The only way around this would be to explicitly configure a mapping for the custom widget that tells EF to ignore the properties which violates my “drop in” design goal.

Whilst we can use read-only properties within our widgets, I’m generally not a fan of auto-anything where I don’t have any control.

Aside from the properties you have already seen on the IWidget interface, there are also a number of convenience methods that handle getting and setting custom widget properties and validating the edit view model.

The final method CreateEditViewModel just updates the common widget properties found on all Widget edit view models.

Now to get a list of all registered IWidget types, I can just have a dependency on IEnumerable<IWidget> and StructureMap will inject a list of Widgets. Simple.

Creating a Widget Instance

To keep things simple I thought I would use the same Create view model for all widgets. This only contains the properties common to all widgets. Once the widget is saved, we can edit the widget and use it’s specific edit view model.

In our GET action we retrieve the Widget instance from our database and return our View passing the widget’s EditViewModel.

The POST action is a little more interesting. We retrieve our Widget instance and use ASP.NET MVC’s UpdateModel helper to automatically update the Widget’s EditViewModel based on the posted FormColleciton. With the EditViewModel updated we call widget.UpdateFromViewModel before persisting all the changes to our database (widgetService.SaveWidget).

Displaying a widget

With our widget instance saved, we now need to display it.

We have a single controller action that is used to display all widgets. This is then called using the RenderAction method (which I’ve wrapped into a little helper method):

In the next post I will cover how to create complex widgets that retrieve data from external services.

Before I get asked whether the source code available for download, the answer is unfortunately not. This was part of a much bigger commercial application so I have done my best to give you all the pieces of the Widget System so that you can build your own.