The Great EPiServer Rant

March 26th, 2010

EPiServer is a CMS, it’s not very well known outside of northern Europe - but here its use is quite extensive, especially in Sweden (since it originated out of our capital, Stockholm). I’ve been working full-time as an EPiServer developer for the better part of two years now, sure few side projects in Wordpress, Code Igniter or some other of the myriad of web platforms/frameworks that exist have been churned out also. But mostly in EPiServer, by far.

First of all let me clarify that I absolutely love to work in .NET, Visual Studio 2008/2010, SQL Server 2005/2008, IIS7.x and the other development tools that Microsoft have out there and MSDN contains some of the best documentation and examples I’ve seen for any software/framework. I’ve worked on several non-EPiServer .NET  projects both personal and professional. Sure .NET, and especially the web platform on older version (WebForms) have its issues, and part of  this rant will touch on that.

After these two years I’ve come to one simple conclusion: EPiServer is not a good piece of software. It’s in fact horrible; overly complicated, badly designed (as in architecture), lacking documentation and has non-existent support.

The Development Process

The main issue with EPiServer is the development process, or rather lack there of. When you just scratch the surface it will look like any standard WebForms project – EPiServer is after all built on top of WebForms – but as soon as you dig a little deeper the severely lacking architecture starts to rear it’s ugly head. The first thing you will learn when you start out is that everything is centered around something called pages, and their internal hierarchy. Your website is described by its page tree, which consists of pages who all have a page type. Each page type has a list of properties associated with it (for example: HeaderText, MainBody, TopImage, etc.) – some of which are standard and can’t be removed, and others that are added by the developer. Each page type has a normal .aspx page responsible for rendering it, the code behind class for this .aspx page inherits from one of several special EPiServer page type base classes.

For example I might have a News page type, which has the properties Header, Date, IntroductionText, BodyText and Image. The News page type is in turned rendered by News.aspx and its associated News.aspx.cs code behind file. I will probably have a lot more page types then just News, for example there will probably be a page type for the StartPage, the Contact Page and a lot of other types to facilitate all the different needs of a site.

As it turns out this is a horrible idea.

The first issue arises quite early, but you won’t realize it’s an issue until far later. The page type and its associated properties are defined in the administration interface of your EPiServer installation. This means that the structure if your site is defined in its database, while the code that uses this structure to render your site is defined within your .aspx and .aspx.cs files. If you’re a lone developer you won’t have any problems with this until you need to deploy a new version to a live server (which means you wont notice it until you’re too invested into EPiServer to switch). However, if your’e more then one developer this architectural idiosyncrasy will bite you a lot earlier. And here’s why:

Since the structure of the website (its page types and their properties) are contained within the database, there is no automated way of porting changes to this structure between different EPiServer installations. There is also no way of using any version control for it, because it’s in the database. This means that changes to either the page types or their properties (and there are a lot of changes to them, constantly, while developing) have to be manually ported between every developer, to keep it all in sync for everyone. You could technically use a central “development” database (which we’ve done on a few projects) that everyone uses. However, since your code depends on the structure within the database, when – not if – someone makes a change to either a page type or a property to accommodate some change in their code it runs a very high risk of breaking your code – for no apparent reason to you.

The second, very big, issue (which I touched briefly on) is that there is no way to version control this structure – which means that if you need to step back several revision with a lot of code changes and associated page type/property changes you need to manually revert the structure by hand to the state that the old code revision needs. And if you can’t remember this structure… well, good luck.

Everything isn’t a page

So every data point in EPiServer is a page, which is an “instance” (for lack of a better word) of a page type. Pages are organized in a tree structure with one parent and several children, which in turn can have children, etc. It just happens to be that everything doesn’t fit nicely into this model. A lot of data can’t be organized into a tree structure with one single parent. This leaves you with two choices; force your non-conforming data into a tree model or use separate tables in the database, next to the EPiServer ones.

The first option of forcing your data into the EPiServer model is the one we usually go with, even though it feels like pushing a 50″ square through a 2″ round hole. You will end up with a horrible amount of custom properties on your data just to accommodate the structure of your data. For example if you want to represent something with two parents, your child page type will end up having a property called Parent2. However there is no way to automatically populate this parent when you create a page, so every time you create a child you need to remember to manually set the Parent2 property of it to the appropriate value.

You will end up with a lot of things that need to be done manually, every time. And there is no easy/obvious way to automate it, all these little things add up to an enormous technical debt in the end. It’s not a matter of if something goes wrong but when, because someone forgot to do that X thing when you do Y that needs to be set when Z your current page.

The second option of storing your data outside the EPiServer architecture might seem like a good way to go then? Well it’s not, while your data and code will be nicer and more in sync, the EPiServer admin interface has no way at all to deal with anything outside the page tree which make up your site. So you have to write your own admin interface for this data.

Which again, leaves you with two options; Extend the EPiServer admin interface or roll a second admin interface to deal with the non-page-data. Rolling a second interface puts you back at square one, why even use a CMS if you need to write a custom admin interface for half of the data in it? We usually go with extending the EPiServer admin interface, to do this you have to deal with JavaScript that is from the dark ages (IE-specific, non-jquery/mootools/etc.) and a pretty much undocumented API.

This lets me segway nicely into the next section…

There is no spoon (or documentation)

This will probably be a pretty short section, which is fitting, due too how short the EPiServer documentation is (you can find it here). There is no proper introduction on how to actually build a site (but they several a courses for this, which you of course have to pay money for) and the topics it touches on it usually leaves you hanging half way, either providing no text and just code – or the other way around (a lot of text, with no code).

Tied into the documentation, sort of, is their support. Which is horrible, a reply usually takes about a week and often you get something along the lines of “we don’t know how to do this”, “this can’t be done” or “you shouldn’t do this”.

Agile – is that a cactus or something?

Agile development is all the buzz today, and while there are people who both like and don’t (as with everything else) – there are quite a few good ideas between all the different methodologies. A big favorite of mine is TDD, which sadly is pretty much impossible to do with EPiServer. A lot of the base classes and libraries are singletons, making them impossible/hard to mock. And if they’re not singletons they’re hidden behind an undocumented interface or base class that is tied so hard into the rest of the system that it’s impossible to isolate and replace it.

You can also say good bye to Continuous Integration, Inversion of Control or any of the other niceties that help your agile process along the way, EPiServer is about as flexible as a bank vault.

The back-end/admin interface is also pretty much set in stone, sure you can add a few panels and buttons but anything more is out of the question – sure you could replace the entire stock back end with a new one, but why are we using a read made CMS in the first place then?

Conclusion

I’ve still not figured out what you pay for when you buy EPiServer, the CMS is at best mediocre both in terms of user- and developer friendliness. The documentation is bad in every imaginable way and the support is slow and incompetent, they have courses that teach you how to use it – but charge you for them. So what does the ~10.000$ EPiServer cost actually buy me?

In the end it all comes down to this; EPiServer makes you pay for something that is in almost every way worse then what it competes with (no matter if it’s open source or some other proprietary CMS), so do yourself a favor and don’t use it.