This actually should be a fairly quick post, but one that I have seen a few times over now. It is simply a quick answer to the following question – ‘how can I get a POCO (object) given the Sitecore item?’. Before you question too much, I will also explain why the answer is (mostly) not GlassCast(this Item item). This question crops up reasonably regularly, especially given the number of pipelines / commands where we are presented with the item as an argument. There are actually a few considerations when looking at this question and some better and worse ways of achieving this. This post covers many of the common mistakes I have seen when using Glass Mapper in my implementations.
Firstly I would start with the following counter question – do you really need to?
Bear in mind that getting the POCO is going to be (slightly) slower than using the item as provided, and the fact that pipelines / commands COULD be very performance critical depending on which one it is. I would definitely say this. Think about what it is you are going to be doing. If it is simply reading a couple of field values and the pipeline is performance critical, then it might well be worth continuing to go ‘old school’ and just using the Sitecore item. If there is going to be a lot of logic performed against the item, then it might well be worth considering the benefit Glass provides in terms of unit testing.
I have seen a few examples of incorrect casts, but this is by far the most annoying:
// not this - this would usually come from the DI container or something. var sitecoreContext = new SitecoreContext(); // this - JUST DON'T! IMyObject myObject = sitecoreContext.GetItem(item.ID); // same or worse goes for using it's path
And yes, I really have seen this done in production code!
This is one of the worse ways to perform this as you already have the item, you are going to force Glass to get the item again, negating any changes you will have made and wasting valuable cycles.
Slightly correct casting
Ok, so – many of you are not daft enough to do the ID trick above, but I do see this reasonably regularly also. Technically it is ‘less correct’ rather than incorrect
// This is ok - but it's not the most efficient. IMyObject myObject = item.GlassCast<IMyObject>();
The reason is – if you look at GlassCast, it does not know how to get to a context, so has to create one, this isn’t HORRENDOUS, but 99% of the time, we already have one we can get at from our DI container or whatever, so why waste the time doing this?
Note – in the latest version of Glass Mapper – the service used in GlassCast is now cached (on a per request basis). This should improve the use of this method, so it’s not AS BIG a sin as previous versions.
The sitecore service and context now have a method Cast(Item item) (this was formerly also there as CreateType(Item item) but now deprecated), this is a very very simple method that returns your object.
// this would usually come from the DI container or something. var sitecoreContext = new SitecoreContext(); // Correct for the older versions of glass IMyObject myObject1 = sitecoreContext.CreateType<IMyObject>(item); // Correct for the current version of glass IMyObject myObject2 = sitecoreContext.Cast<IMyObject>(item);
This is one of many tips I intend to share on my experience with Glass. Remember – this is MY experience of Glass Mapper, I love it because it’s such a versatile tool and because of this – easy to manipulate and do things like my methods OR differently. I would invite feedback from anyone whether it is for something to cover or alternative’s.