Category Archives: Refactoring

Pagination in MvcContrib

Over the next month or so, I’m hoping to write a couple of posts on some work I’ve undertaken in extending the original pager implementation that compliments the MvcContrib grid component.

The work I’ve undertaken so far has focused on the following areas:

Customisable Pager Rendering

The existing pager is rather limited in the HTML rendered out of the box. Currently the only means to gaining more control over the output would be to inherit from the existing Pager, override a few methods (you’d probably need to dig into the source to identify which ones), and to implement a new HTML helper. Support for this approach is limited by the current unit tests making expectations based on the complete mark-up.

The new pager will support complete customisation of rendering through custom templates, and

Support for Numeric Pagination (in addition to Next/Previous)

The existing pager component outputs as a “Next/Previous” style pager, with links for next/previous/first/last.

The new pager implementation will allow a choice of pager, with Next/Previous and Numeric pagers provided OOTB.

Separate Pagination Summary

Although the existing pager provides a summary with localization support, its implementation is embedded within the current pager. I would like to break this component out and separate its unit tests from the pager implementation, such that this component is optional and can change independently from the pager.

I’m looking for feedback on the work I’ve undertaken so far, and would welcome additional ideas and suggestions. The fork containing my work so far can be found here: https://hg01.codeplex.com/forks/craigcavalier/pagerextensions

Advertisements

Refactoring a static method (on a generic class) to an extension method‏

The Goal

I needed to perform this refactoring today, and it took me a few mins to figure out how to do this in a safe way using resharper. My goal was to refactor usages like:

Mapper<DestinationType>.Map(Source)

to use an extension method so I can use the syntax similar to:

Source.MapTo<DestinationType>();

which I find to be less verbose, more discoverable, and more readable. This however was slightly more difficult than I hoped; resharper didn’t let me do this in a single step (how lazy of me).

The Problem

The original code* looked similar in structure to this:

public abstract class Mapper<TDestination>

{

   public static TDestination Map(object source)

   {

      //do mapping here

      return destination;

   }

}

Since Mapper is not a static class, we cannot use resharpers built in “convert static to extension method” refactoring straight up; extension methods can only live in a static class. We could move this method to a static class, say MapperExtensions, such that we can perform “convert static to extension method”, but to do this we also require the generic type parameter TDestination that lives on the Mapper class. There isn’t a refactoring (that I am aware of/could find with a quick google) to add a generic type parameter to a method signature and adding this in by hand would break all my code that invokes this method. We cannot make the Mapper class static either, since it is an abstract class. This was looking like it could be a bit of a pain.

*The example (mapping) is actually contrived – I’ve made up a example here that is representative of the structure of the problem, rather than use the actual code. This was to avoid breaching the IP rules of the company I work for. In an actual mapper, the Map method is more likely to be an instance method rather than static, and since Mapping it is the primary responsibility of the class, it is not advisable for the Map method to be implemented as an extension method.

The Solution

Step 1: Extract Method

First of all, we can use the extract method refactoring to extract the contents of the original method into another method. We can then use this newly created method as a base to make a any further changes (like adding the generic type parameter) without breaking anything that invokes our original code. After this step, we have:

public abstract class Mapper<TDestination>

{

   public static TDestination Map(object source)

   {

      return MapTo<TDestination>(source);

   }

   public static TDestination MapTo<TDestination>(object source)

   {

      //do mapping here

      return destination;

   }

}

Step 2: Move Method

Since we now have a static method with the required generic type parameter, we can now use the “Move Method” refactoring to move MapTo to its new home, the static class MapperExtensions.

Step 3: Convert static to extension method

We’re now all set to use this refactoring – and we’re nearly there!

Step 4: inline method

We can now make the original call to Map an inline method. This will essentially replace all existing calls from using Map to use the MapTo extension method.

The End Result

The finished article now looks like this:

public static class MapperExtensions

{

   public static TDestination MapTo<TDestination>(this object source)

   {

      //do mapping here

      return destination;

   }

}

Now we’re talking!