EPiServer  /  CMS July 23, 2009

Page Type Builder 0.8 released – Finally!

Today I released version 0.8 of Page Type Builder. This release features a complete overhaul of the page-type-updating process, some nice new features and quite a lot of changes. It also shows that it’s hard to find a good version numbering strategy ;)

It’s all rewritten

When I begun this project it was pretty much just an experiment and therefore I didn’t put as much energy into making the code maintainable as I should have. Since the first version (0.1) in early June the project has gotten some positive attention and has quickly grown from just an experiment to being used in real customer, both by us at Nansen and at a few other EPiServer partners and I realized that I needed to make the code more maintainable, both structure wise but also by creating a suite of regression tests for it. It took me a few weeks and quite a few late night hours but I’m glad to say that that has been done for this release. There still is quite a lot of refactoring needed but doing so with the tests 150+ that has been written for this release should be relatively pain free. During this process I’ve also eliminated a few nasty bugs in the page-type-synchronizing process from the previous version.

PageDataFactory is dead – hail DataFactory

In version 0.7 I added the PageDataFactory class which wrapped DataFactory and returned PageData objects with the correct underlying type. In this version PageDataFactory is removed and Page Type Builder listens to events from DataFactory when it has loaded a page, intercepts it and replaces it with a copy that has the correct underlying type. That is, we can now do things like this:

MyPageType page = (MyPageType)DataFactory.Instance.GetPage(123);

Except that PageDataFactory provided objects with the correct underlying type it also had a few convenience methods, such as GetPublishedChildren. These are gone for now. I will probably create some sort of extension project later on with extension methods for DataFactory. PageDataFactory also enabled us to decouple our code from DataFactory as it was possible to create mock objects that could be used in it’s place. Losing this is a shame but it wasn’t really Page Type Builders purpose and I think and hope EPiServer will make that possible with DataFactory in the future.

So far I’ve tested this, modifying what DataFactory returns, for GetPage, GetChildren and GetPagesWithCriteria. It definetly works with GetPage and GetChildren and it also seems to work with GetPagesWithCriteria (I haven’t tested it thoroughly enough to say with certainty that it works in all situations). If for some reason we are unable to get a PageData object with the correct underlying type from DataFactory Page Type Builder also provides a method named ConvertToTyped in the PageTypeResolver class which will do the trick.

TemplatePage<T> and UserControlBase<T>

The project now contains the two classes TemplatePage<T> and UserControlBase<T> which directly inherits from TemplatePage and UserControlBase but whose CurrentPage property is of type T instead of PageData so we can directly access the current page in a strongly typed fashion. If the current page is not of type T, which by the way has to be TypedPageData or a subtype of it, a exception with a fairly descriptive message will be thrown.

Easier to read and write GetPropertyValue and SetPropertyValue methods

The GetProperyValue and SetPropertyValue methods have been moved from TypedPageData to extension methods. They have also been modified so that we don’t explicitly have to specify the page type or property type as long as the EPiServer property type is compatible with the code property type. If it isn’t we can still explicitly specify the type the old way.

In other words, instead of implementing a property like this:

[PageTypeProperty(Type = typeof(PropertyString))]
public string Headline
        return GetPropertyValue<MyPageType, string>
            (page => page.Headline);

We can now implement it like this:

[PageTypeProperty(Type = typeof(PropertyString))]
public string Headline
        return this.GetPropertyValue(page => page.Headline);

Autoimplenting properties

As if the above method wasn’t easy enough it’s now also possible to let Page Type Builder automatically implement properties for us. We simply create automatic properties and set them as virtual and we’re done. In other words, the example above can be written like this with the same result:

[PageTypeProperty(Type = typeof(PropertyString))]
public virtual string Headline { get; set; }

It’s almost as we’re back to the simplicity of (string) CurrentPage.GetValue(“Headline”) but with strongly typed property access! :)

Future improvement

As I said before there is quite a lot of refactoring to do before the project reaches version 1.0. Other than that I will focus on:

  • Creating a better way to work with tabs
  • Making the startup process faster by only updating page types that needs to be updated and possibly only look for page types in a set of configured assemblies
  • Creating methods for strongly typed access to dynamic properties
  • Perform better validation of page types and changing it so that any error message is displayed all the time. At the moment they are only displayed at first request.

Credit, a lot of credit

Almost all of the changes and additions in this version has been heavily inspired, and some even coded by, Cristian Libardo and Daniel Rodin with awesome blog post such as this and this. Please keep it coming guys! Oh and Cristian, I hope I didn’t mess up your code to much :)

Super exciting fun facts

Almost last but not least, did you know that Page Type Builder consist of 461 lines of code (or 2339 IL instructions), that it’s distance from the main sequence is 0,1 and that it’s relational cohesion is 1,81? Oh, and did you know the test suite consists of 1159 lines of code and offers 88% code coverage? Well, thanks to NDepend and me being bored, now you know.

Feedback, feedback, give me feedback!

As always I’m ending a blog post about this project with a request for feedback. Any and all feedback is very welcome and greatly appreciated! Have you tried using PTB? What did you like? What didn’t you like? If you haven’t tested it, why not?

For the latest updates on the project make sure to check out the projects site on CodePlex. And this blog of course :)

PS. For updates about new posts, sites I find useful and the occasional rant you can follow me on Twitter. You are also most welcome to subscribe to the RSS-feed.

Joel Abrahamsson

Joel Abrahamsson

I'm a passionate web developer and systems architect living in Stockholm, Sweden. I work as CTO for a large media site and enjoy developing with all technologies, especially .NET, Node.js, and ElasticSearch. Read more


comments powered by Disqus

My book

Want a structured way to learn EPiServer 7 development? Check out my book on Leanpub!

More about EPiServer CMS