Monday, March 31, 2014

Gallery Server Pro DotNetNuke Module History and Roadmap

Gallery Server Pro has been available as a DotNetNuke module since 2.4.0 was released in 2010. Subsequent releases of Gallery Server Pro have always had a corresponding DNN module release…until 3.0 was released in June 2013. Version 3 was a significant release, introducing—among other things—a new data layer built on Entity Framework Code First Migrations 5.0. Using EF CF Migrations greatly simplified data access, as we no longer had to maintain separate code bases for each database technology (that is, SQL Server and SQL CE).

However, EF CF Migrations had a limitation that was incompatible with DNN—one could have only one migration model per database. Since the GSP module shared its data access with a variety of other modules as well as the DNN core, it would be asking for trouble for the module to assume it could have the only allowed migration model in the database.

But there was hope, as the EF team recognized this issue and promised to support multiple models in 6.0. And so we put the 3.0 version of the GSP DNN Module on hold until EF 6 was released. Indeed, they delivered on their promise in October 2013. We eagerly upgraded to this version as we prepared to hunker down on the DNN module. Unfortunately, we immediately hit a snag. The ASP.NET Universal Provider library, which is used to provide membership and role services, didn’t work with EF6. Microsoft recognized this and resolved the issue when they released Microsoft ASP.NET Universal Providers Core 2.0 in December 2013.

Finally, the pieces were in place to proceed with the GSP DNN module.

Unfortunately, more roadblocks…

In the last few weeks we’ve been sitting down and taking a serious look at what it’ll take to merge the GSP 3.0 code with the GSP DNN module 2.6 source code. Despite resolving the initial roadblocks, significant hurdles remained.

Lack of DNN support for EF CF Migrations

DNN assumes that a module builder follows a specific data architecture that involves generating the required data structure as SQL script files that are executed by the DNN module installer. Then all data access is performed by executing manually-generated SQL statements against the database or invoking stored procedures.

But EF CF Migrations generates and executes the SQL for us, making integration with the DNN architecture problematic. We tried to find out if and how others were building DNN modules using EF CF Migrations but couldn’t find anyone who is doing this. At this point it is not clear to us whether it is even possible. We don’t mind being trailblazers when appropriate, but we’d rather not take on a huge amount of risk when dealing with something as mundane as accessing the database.

JavaScript and jQuery widget issues

Version 3 dramatically increased the number of jQuery widgets. These widgets provide a lot of flexibility and work well with the jsRender-based UI template architecture. But jQuery widgets are tricky to use in an environment where others may be using the same—or similar—widgets. For example, how does one handle the situation where two modules are on the page, and each module uses a different version of jsTree? In reality, you can’t make it work unless you jump through hoops like building a forked version of jsTree with a custom name.

There are other risks as well. The increased use of JavaScript everywhere (the GSP DNN module, other 3rd party modules, and the DNN core) has increased the risk of conflict and hard to find bugs. For example, GSP adds a trim() method to the String object when it’s missing:

if (!String.prototype.trim) {
   // Add trim() function for browsers that don't implement it (IE 1-8).
   String.prototype.trim = function () {
     return this.replace(/^\s+|\s+$/g, '');

What if another module beats us to it and defines its own implementation? We get unexpected behavior and you think there’s a bug in GSP. As you can imagine, this type of issue is pretty much impossible to test for or prevent with any degree of certainty.

web.config changes

All ASP.NET applications share a web.config file in the root that defines certain behaviors. GSP has this as well, where we define things such as the EF version, the membership provider, and Web.API configuration. The DNN module version of GSP also requires most of these things in the web.config file. But since this file affects the entire application, including other modules, there is a substantial risk that the configuration required for GSP conflicts with someone else’s configuration requirements.

Furthermore, Web.API requires setting up routes so that ajax requests get sent to the correct controller. GSP defines what it needs, but these may conflict with routes defined in other modules or the DNN core.

Object qualifier and database owner

DNN recommends that tables be created with support for a custom object qualifier and database owner. That means the SQL scripts that create the tables look something like this:

CREATE TABLE {databaseOwner}[{objectQualifier}gs_Album](...)

Since EF CF Migrations generates tables by reverse engineering the code first model, support for this kind of customization is difficult or possibly impossible. Skipping support for this leads to the possibility of a module installation damaging the database if a user attempts to install the module on two different installations hosted inside the same database. Not cool.

Decline of DNN

Perhaps the most significant issue for us is the signs that the DNN ecosystem is dying. Take a look at this chart generated from Google Trends:


Searches for the term DotNetNuke peaked in 2006 and have dropped to almost nothing since then. Much of this, of course, is the name change from DotNetNuke to DNN. But even the term DNN peaked between 2006 and 2009 and is down by about 50% since then.

There are other signs, too. Go to any job site and compare the jobs for DNN with those of other CMS’s. DNN is dwarfed by jobs for WordPress, Drupal and Joomla. Even among .NET CMS’s, Umbraco has overtaken DNN as the go-to CMS.

Sales of the GSP DNN module have never been great. We have yet to recover the resources we have put into it over the years.

The unknown

Developing the GSP DNN module in 2010 took far longer than we expected due to surprises we encountered along the way. For example, DNN disables the native .NET localization services GSP used to provide language support. We spent a ridiculous amount of time trying to figure out how to get DNN to serve text from GSP’s resx file. We fear more such issues as we ponder the 3.0 migration.

Moving forward

The issues described above have been heavily weighing on our minds, and we had to make a decision about how to move forward. If we poured resources into supporting DNN, it takes away from adding cool new features to the core GSP product. More importantly, we're not sure it's even possible for GSP 3 to run as a DNN module. At the very least, it would be significant undertaking.

Ultimately, we have decided to no longer support DNN. That’s a painful sentence to write, as it’s like abandoning one of our children. Plus, we know there are many of you who have been looking forward to continued DNN support. But we need to do what serves the greatest good for the most customers, while allowing us to keep paying the bills.

If you currently use GSP DNN Module 2.6, be assured it will continue to work indefinitely. And remember that you can always install the latest version of GSP as a stand-alone instance and link to it from your DNN site.

As for us, we are putting the finishing touches on a 3.2 release. This will be a free update to all 3.X license holders. Details will be shared soon. After that, we’ll be hunkering down on version 4.0, where we plan several significant features you’re just going to love.

The future of GSP is bright, and we love that you’re coming along with us for the ride. Great things to come!