A List of Books That Every Sitecore Developer Should Read
Not sure if you know — those who follow me on Twitter definitely know — but I am very passionate around improving my craft. I typically do so through reading whatever I can get my hands on — this includes blog posts, tweets, threads on the Sitecore Community site and, most especially, software development books.
Since a lot of people know that I read a ton of books, I am frequently asked on what software development books I recommend. A few years ago, I had a huge list of recommended books that I could easily share via email but that was many computers ago, and I no longer have that list. I’m hoping this blog post can serve as a replacement for it.
I have read every book on this list, and recommend them all. I hope you find them as beneficial as I have.
Keep in mind that this list is not final. I am going to keep adding to it as I read more, or remember other books that I’ve read and recommend (I used to have a library of about 900 books with a diverse set of subjects including Psychology, Sociology, Theoretical Physics, Computer Science and Software Development but donated all but 5 books to charity in 2013).
Sitecore Development
-
Professional Sitecore Development by John West
http://www.amazon.com/Professional-Sitecore-Development-John-West/dp/047093901X
Software Engineering/Software Development/Software Craftsmanship
-
Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin
http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882 -
Agile Principles, Patterns, and Practices in C# by Robert C. Martin
www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258 -
The Clean Coder: A Code of Conduct for Professional Programmers by Robert C. Martin
http://www.amazon.com/Clean-Coder-Conduct-Professional-Programmers/dp/0137081073/ -
Refactoring: Improving the Design of Existing Code by Martin Fowler
http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672 -
Working Effectively with Legacy Code by Michael Feathers
http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052/ -
The Pragmatic Programmer: From Journeyman to Master by Andrew Hunt and Dave Thomas
http://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X/ -
The Mythical Man-Month: Essays on Software Engineering by Frederick P. Brooks Jr.
http://www.amazon.com/Mythical-Man-Month-Software-Engineering-Anniversary/dp/0201835959/ -
The Passionate Programmer: Creating a Remarkable Career in Software Development by Chad Fowler
http://www.amazon.com/The-Passionate-Programmer-Remarkable-Development/dp/1934356344/ -
Dependency Injection in .NET by Mark Seemann
http://www.amazon.com/Dependency-Injection-NET-Mark-Seemann/dp/1935182501/ -
Implementation Patterns by Kent Beck
http://www.amazon.com/Implementation-Patterns-Kent-Beck/dp/0321413091/ -
Pragmatic Thinking and Learning: Refactor Your Wetware by Andy Hunt
http://www.amazon.com/Pragmatic-Thinking-Learning-Refactor-Programmers/dp/1934356050/
Design Patterns
-
Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (The Gang of Four)
http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612/ -
Head First Design Patterns by Eric Freeman, Bert Bates, Kathy Sierra, Elisabeth Robson
http://www.amazon.com/Head-First-Design-Patterns-Freeman/dp/0596007124/ -
Design Patterns Explained: A New Perspective on Object-Oriented Design by Alan Shalloway
http://www.amazon.com/Design-Patterns-Explained-Perspective-Object-Oriented/dp/0321247140/ -
Programming in the Large with Design Patterns by Eddie Burris
http://www.amazon.com/Programming-Large-Design-Patterns-Burris/dp/0615662145/ -
Pattern Hatching: Design Patterns Applied by John Vlissides
http://www.amazon.com/Pattern-Hatching-Design-Patterns-Applied/dp/0201432935/ -
Refactoring to Patterns by Joshua Kerievsky
http://www.amazon.com/Refactoring-Patterns-Joshua-Kerievsky/dp/0321213351/
JavaScript
-
JavaScript: The Good Parts by Douglas Crockford
http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742/
UML
-
UML Distilled: A Brief Guide to the Standard Object Modeling Language by Martin Fowler
http://www.amazon.com/UML-Distilled-Standard-Modeling-Language-ebook/dp/B000OZ0N8A/
SCRUM/Agile
-
Agile Estimating and Planning by Mike Cohn
http://www.amazon.com/Agile-Estimating-Planning-Mike-Cohn/dp/0131479415/ -
Succeeding with Agile: Software Development Using Scrum by Mike Cohn
http://www.amazon.com/Succeeding-Agile-Software-Development-Using/dp/0321579364 -
Agile Retrospectives: Making Good Teams Great by Esther Derby, Diana Larsen, Ken Schwaber
http://www.amazon.com/Agile-Retrospectives-Making-Teams-Great/dp/0977616649/ -
Coaching Agile Teams: A Companion for ScrumMasters, Agile Coaches, and Project Managers in Transition by Lyssa Adkins
http://www.amazon.com/Coaching-Agile-Teams-ScrumMasters-Addison-Wesley/dp/0321637704/ -
The Art of Agile Development by James Shore
http://www.amazon.com/The-Agile-Development-James-Shore/dp/0596527675/
Unit Testing
-
The Art of Unit Testing: with Examples in .NET by Roy Osherove
http://www.amazon.com/Art-Unit-Testing-Examples-NET/dp/1933988274/ -
Test Driven Development: By Example by Kent Beck
http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530/
If you have any books that you would like to recommend, please share in a comment.
Until next time, keep on learning and keep on Sitecoring!
Make Incompatible Class Interfaces Work Together using the Adapter Pattern in Sitecore
This post is a continuation of a series of blog posts I’m putting together around using design patterns in Sitecore, and will share a “proof of concept” on employing the Adapter pattern — a structural pattern used when you need classes of different interfaces to work together. In other words, you need one class’ interface to “adapt” to another.
Believe it or not, most developers — and hopefully most reading this post — are already quite familiar with the Adapter pattern even if it’s not recognizable by name.
How so?
Well, I don’t know about you but I spend a lot of time making code from different APIs work together. I typically have to do this when making use of a third-party library that I cannot change, and usually do this by having one class “wrap” another and its methods. Commonly, the Adapter pattern is known as a “wrapper”.
I showcased the following “proof of concept” during my presentation at SUGCON Europe 2015. This code flips images upside down after they are uploaded to the Media Library — yeah, I know, pretty useful, right? 😉 Keep in mind this code is for educational purposes only, and serves no utility in any practical sense in your Sitecore solutions — if you do have a business need for flipping images upside down after uploading them to the Media Library, please share in a comment.
I first started off with the following interface:
using Sitecore.Data.Items; namespace Sitecore.Sandbox.Resources.Media { public interface IMediaImageFlipper { MediaItem MediaItem { get; set; } void Flip(); } }
Classes that implement the interface above basically flip images within Sitecore.Data.Items.MediaItem instances — this is defined in Sitecore.Kernel.dll — upside down via their Flip() method.
The following class implements the above interface:
using System; using System.Collections.Generic; using System.Linq; using System.IO; using Sitecore.Data.Items; using Sitecore.Diagnostics; using ImageProcessor; namespace Sitecore.Sandbox.Resources.Media { public class ImageFactoryFlipper : IMediaImageFlipper { public MediaItem MediaItem { get; set; } private List<string> TargetMimeTypes { get; set; } private ImageFactory ImageFactory { get; set; } public ImageFactoryFlipper() : this(new ImageFactory()) { } public ImageFactoryFlipper(ImageFactory imageFactory) { TargetMimeTypes = new List<string>(); Assert.ArgumentNotNull(imageFactory, "imageFactory"); ImageFactory = imageFactory; } public void Flip() { if (!ShouldFlip(MediaItem)) { return; } using (MemoryStream outputStream = new MemoryStream()) { ImageFactory.Load(MediaItem.GetMediaStream()).Rotate(180.0f).Save(outputStream); using (new EditContext(MediaItem)) { MediaItem.InnerItem.Fields["Blob"].SetBlobStream(outputStream); } } } protected virtual bool ShouldFlip(MediaItem mediaItem) { if (mediaItem == null || string.IsNullOrWhiteSpace(mediaItem.MimeType) || !TargetMimeTypes.Any() || ImageFactory == null) { return false; } return TargetMimeTypes.Any(targetMimeType => string.Equals(targetMimeType, mediaItem.MimeType, StringComparison.CurrentCultureIgnoreCase)); } } }
In the above class, I am “wrapping” an ImageFactory class instance — this class comes with the ImageProcessor .NET library which does some image manipulation (I found this .NET library via a Google search and have no idea how good it is, but it’s good enough for this “proof of concept”) — and inject it using Poor man’s dependency injection via the default constructor.
The Flip() method is where the magic happens. It calls the ShouldFlip() method which ascertains whether the MediaItem property is set on the class instance and whether the image found within it should be flipped — an image should be flipped if it has a MIME type that is within the list of MIME types that are injected into the class instance via the Sitecore Configuration Factory (see the patch configuration file below).
If the image should be flipped, the Flip() method uses the ImageFactory instance to flip the image upside down — it does this by rotating it 180 degrees — and then saves the flipped image contained within the MemoryStream instance into the MediaItem’s Blob field (this is where images are saved on Media Library Items).
Now that we have a class that flips images, we need a MediaCreator — a subclass of Sitecore.Resources.Media.MediaCreator (this lives in Sitecore.Kernel.dll) — to leverage an instance of the IMediaImageFlipper to do the image manipulation. The follow class does this:
using System.IO; using Sitecore.Data.Items; using Sitecore.Resources.Media; namespace Sitecore.Sandbox.Resources.Media { public class ImageFlipperMediaCreator : MediaCreator { private IMediaImageFlipper Flipper { get; set; } public override Item CreateFromStream(Stream stream, string filePath, bool setStreamIfEmpty, MediaCreatorOptions options) { MediaItem mediaItem = base.CreateFromStream(stream, filePath, setStreamIfEmpty, options); if (Flipper == null) { return mediaItem; } Flipper.MediaItem = mediaItem; Flipper.Flip(); return mediaItem; } } }
After an image is uploaded to the Media Library, we pass the new MediaItem to the IMediaImageFlipper instance — this instance is injected using the Sitecore Configuration Factory (see the configuration file below) — and invoke its Flip() method to flip the image, and return the new MediaItem when complete.
I then utilize an instance of the MediaCreator above in a subclass of Resources.Media.MediaProvider.MediaProvider (I am going to replace the “out of the box” MediaProvider with the following class using the configuration file below):
using Sitecore.Diagnostics; using Sitecore.Resources.Media; namespace Sitecore.Sandbox.Resources.Media { public class ImageFlipperMediaProvider : MediaProvider { private MediaCreator FlipperCreator { get; set; } public override MediaCreator Creator { get { return FlipperCreator ?? base.Creator; } set { Assert.ArgumentNotNull(value, "value"); FlipperCreator = value; } } } }
The MediaCreator that lives in the FlipperCreator property is injected into the class instance through the Sitecore Configuration Factory (see the patch configuration file below), and is returned by the Creator property’s accessor if it’s not null.
I then registered all of the above in Sitecore using the following patch configuration file:
<?xml version="1.0" encoding="utf-8" ?> <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> <sitecore> <mediaLibrary> <mediaProvider> <patch:attribute name="type">Sitecore.Sandbox.Resources.Media.ImageFlipperMediaProvider, Sitecore.Sandbox</patch:attribute> <FlipperCreator type="Sitecore.Sandbox.Resources.Media.ImageFlipperMediaCreator, Sitecore.Sandbox"> <Flipper type="Sitecore.Sandbox.Resources.Media.ImageFactoryFlipper, Sitecore.Sandbox"> <TargetMimeTypes hint="list"> <TargetMimeType>image/jpeg</TargetMimeType> <TargetMimeType>image/png</TargetMimeType> </TargetMimeTypes> </Flipper> </FlipperCreator> </mediaProvider> </mediaLibrary> </sitecore> </configuration>
Let’s test this.
I selected the following images for uploading to the Media Library:
As you can see, all uploaded images were flipped upside down:
If you have any thoughts on this, or examples where you’ve employed the Adapter pattern in your Sitecore solutions, please share in a comment.
Until next time, have a Sitecorelicious day!