In SP2 of EPiServer CMS 5 R2, that is the latest currently released version, two new methods with a bunch of overloads where added to DataFactory, GetPage<T>() and GetChildren<T>(). They where added to support Fredrik Tjärnbergs Page Type Tool and where implemented using another newly added method, PageData.ShallowCopy<T>(). Their implementation is such that if you do something like the code below GetPage<T>() will always return an instance of the requested type:
MyPageType page = DataFactory.Instance.GetPage<MyPageType>(aPageReference);
This is all good as long as the requested PageData object actually is of a page type that matches the MyPageType class or a subtype of it. But what happens if it isn’t and it’s actual page type doesn’t have a one of it’s properties? Then the above code will still execute without a problem but the code below will throw an exception:
int number = page.SomeRequiredNumberProperty;
This illustrates my first problem with the GetPage<T>() and GetChildren<T>() methods - they are deceiving in that they will always give you what you want, even if it’s wrong. Also, let’s say you are using Page Type Builder and are new to using it. Then it’s really hard to figure out what went wrong. Is it a bug in the page type, or perhaps in Page Type Builder?
Another problem from a Page Type Builder perspective is that when the requested PageData object’s page type matches the requested type Page Type Builder will already have used ShallowCopy (the one without a type parameter) once to replace the returned PageData object and these methods will add some (minor) unnecessary overhead.
I would really like to see this problem fixed in the final release of CMS 6 as my guess is that it will be very hard to fix it after it’s release, having then to maintain a stricter backwards compatibility with previous releases in the same major release series. Preferably I would like to see one of two solutions.
Either remove the methods. This would also allow others to add methods with the same signatures as extension methods to DataFactory.
Alternatively change their implementation from using ShallowCopy<T>() to something like the code below, making the methods non-deceiving.
public TPageData GetPage<TPageData>(PageReference pageLink) where TPageData: PageData, new()
{
return this.GetPage(pageLink) as TPageData;
}
I really hope you find one of these two options viable. However, if you don’t then please fire an event before the call to ShallowCopy<T>() in the methods . That way Page Type Builder, and anyone else, can listen to it and throw an exception if the requested PageData object really isn’t of the requested type.
Hopefully, Joel
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.
This blog is built with EPiServer Community, EPiServer CMS, ASP.NET MVC and a bunch of other great products. The source code is available for download at the projects page, where you also can read more about this site and my other projects.
read more
Comments
Ronald Widha 7 months ago
I haven't used the strongly type GetPage before, but by the sound of it it doesn't do anything else but to box the result as T. If that's the case, I;m 100% agree to what you're saying. It should check whether the page is indeed of the same type, otherwise fails.
your implementation would be perfect as it also makes TPageDataBase possible.
Paul Smith 7 months ago
Hi Joel,
I will look into this straight away but I can't promise anything right now.
Paul Smith, EPiServer Backend Team Leader
Joel Abrahamsson 7 months ago
Thanks Paul, that's all I can ask for :)
I am however willing to bet a hefty sum that you guys will regret it later on, especially if you plan on including functionality similar to PTB's in the future, if you don't tackle this problem before CMS 6 is released. And since these methods where added in SP2 there shouldn't be many sites that use them, and my guess is that the few that do uses them together with PTB, which from PTB's perspective is a bad practice.