Custom Glass.Mapper Data Handlers – Part 2

In a previous post about extending Glass Mapper to handle custom data types I shared some code which I felt was overly verbose and I did not like the amount of code that had been copy/pasted. The example I used was a fairly trivial one, but it’s always good practice to try avoid copy/paste in case some point in the future the base implementation is changed. It might not always be clear to future developers how that piece of code had come about.

In that original post, Mike Reynolds (a.k.a sitecorejunkie) suggested use of the Decorator Pattern to wrap an instance of the base mapper and delegate some of the methods. Well it got me feeling uneasy and I finally found a little time to come back and clean that code up, I went a slightly different route and decided to use constructor overloading.

By creating an overloaded constructor for my new type, we can pass in an instance of the original field type being extended and map across the data:

public class ExtendedFile : Glass.Mapper.Sc.Fields.File
{
	public ExtendedFile(File file)
	{
		base.Id = file.Id;
		this.Src = file.Src;
	}

	public new string Src { get; internal set; }
	public string Md5Hash { get; set; }
	public long Size { get; set; }
}

Downside is if there are a lot of properties then you have to map them all. If it gets crazy then you could look at AutoMapper.

And then the extended data mapper becomes a lot simpler too:

public class SitecoreFieldExtendedFileMapper : SitecoreFieldFileMapper
{
	public override object GetField(Field field, SitecoreFieldConfiguration config, SitecoreDataMappingContext context)
	{
		FileField fileField = new FileField(field);
		File file = base.GetField(field, config, context) as File;

		// Custom field type pass in the base Glass resolved type
		ExtendedFile extFile = new ExtendedFile(file);

		if (fileField.MediaItem != null)
		{
			// Extended File Attributes
			extFile.Md5Hash = fileField.MediaItem[IFileExtensionConstants.MD5HashFieldName];
			extFile.Size = ((MediaItem) fileField.MediaItem).Size;
		}

		return extFile;
	}

	// Overridden method which dictates which Field Types this class handles
	public override bool CanHandle(Glass.Mapper.Configuration.AbstractPropertyConfiguration configuration, Context context)
	{
		return configuration is SitecoreFieldConfiguration &&
			   configuration.PropertyInfo.PropertyType == typeof(ExtendedFile);
	}
}

We can simply override the CanHandle() method and update the logic check for which types of classes this should handle.

I’m pretty happy with the cleanliness of this and protection against future updates in Glass.

Leave a comment