Saturday, December 19, 2009

Refactoring my MVC & Photo Repository

If you’ve been keeping up with my blog, you know that I’ve been working on my wife’s new website. Well, this post is going to involve a bit of refactoring on some of the code mentioned in the following previous posts.

The main thing I’m going to be talking about is the way I’m handling the different images on all the different pages. So let’s get started.

We’ll start with my IPhotoRepository (resides in Core) interface that originally looked like this:

    public interface IPhotoRepository
{
IList<Photo> GetHomePhotos();
IList<Photo> GetPhotosBy(string portfolio);
}

It ended up growing to look like this and it started to SMELL!

    public interface IPhotoRepository
{
IList<Photo> GetHomePhotos();
IList<Photo> GetContactPhotos();
IList<Photo> GetSessionPhotos();
IList<Photo> GetPhotosBy(string portfolio);
}

I did some refactoring and now it looks like this:

    public interface IPhotoRepository
{
IList<Photo> GetPhotosFor(Enumeration photoViewType);
IList<Photo> GetPhotosBy(string portfolio);
}

Okay, so my implementation called PhotoRepository (resides in Impl) now looks like this:

    public class PhotoRepository : IPhotoRepository
{
public IList<Photo> GetPhotosFor(Enumeration photoViewType)
{
return GetPhotosBy(photoViewType.DisplayName);
}

public IList<Photo> GetPhotosBy(string portfolio)
{
var flickr = new Flickr("yourflickerapikey");
var ps = flickr.PhotosSearch("yourflickruserid", portfolio, PhotoSearchExtras.OriginalFormat);
return Mapper.Map(ps.PhotoCollection, new List<Core.Domain.Model.Photo>());
}
}

The main difference is the addition of the Enumeration (resides in Core) class, which I literally copied off Jimmy Bogard’s blog post here. I believe you can also see it in use within the Code Camp Server project.


The Enumeration class I pass in is called PhotoViewType (resides in UI) and it’s implementation looks like this:

    public class PhotoViewType : Enumeration
{
protected PhotoViewType() { }
protected PhotoViewType(int value, string displayName) : base(value, displayName) { }

public static readonly PhotoViewType Home = new PhotoViewType(0, "Home");
public static readonly PhotoViewType Sessions = new PhotoViewType(1, "Sessions");
public static readonly PhotoViewType Contact = new PhotoViewType(2, "Contact");
}

I also refactored my view models. I basically extracted out the Photos and created a PhotoView() that returns a ViewResult. Here’s what the model looks like:


image I’m going to go ahead and show you the GetRandomIndex method just because I think it’s a good example of easy to read code and I’ll show my first implementation of it too. You can decide which is better!


First Implementation:

        private int GetRandomIndex()
{
return new Random().Next(0, Photos.Count);
}

More readable implementation…I think. It makes more sense to me and is simpler for someone to understand what’s going on.

        private int GetRandomIndex()
{
var minIndex = 0;
var maxIndex = Photos.Count;

return new Random().Next(minIndex, maxIndex);
}

So, I created a new SmartPhotoController that inherits from my base controller called SmartController. The SmartPhotoController has the responsibility of getting me my photos basically. The implementation looks like this:

    public class SmartPhotoController : SmartController
{
private readonly IPhotoRepository _photoRepository;
public SmartPhotoController(IPhotoRepository photoRepository)
{
_photoRepository = photoRepository;
}

protected ViewResult ViewWithPhotos<TModel>(TModel viewModel, Enumeration photoViewType)
where TModel : PhotoView
{
viewModel.Photos = _photoRepository.GetPhotosFor(photoViewType);
return View(viewModel);
}
}

I originally had the ViewWithPhotos<TModel> look like this:

protected ViewResult ViewWithPhotos<TModel>(TModel viewModel, Func<IPhotoRepository, IList<Photo>> func)
where TModel : PhotoView
{
viewModel.Photos = func(_photoRepository);
return View(viewModel);
}

I thought that was really cool because when I called it from my controller, it looked like this: ViewWithPhotos(new HomeView(), x => x.GetHomePhotos()); Obviously, I refactored my repository, so it was no longer necessary to do the lambda or the generic func. I think it’s unfortunate because I love lambdas, but they tend to confuse people so I usually end up refactoring them out with something easier to understand. My new code from the controller looks like this: ViewWithPhotos(new HomeView(), PhotoViewType.Home); So now my Home, Sessions, & Contact controllers inherit from the SmartPhotoController because they all deal with photos in some way.


I guess that’s it for now. As always, please comment if you see anywhere that I could improve or you just have a comment. Thanks for reading!

kick it on DotNetKicks.com

blog comments powered by Disqus
Related Posts Plugin for WordPress, Blogger...