BT

AutoMapper and the Static Class Debate

by Jonathan Allen on Mar 07, 2016 |

When it comes to API design, static classes are a bit of a bugbear. Quite often there are arguments both for and against exposing a given function as a static function as opposed to an instance method.

The primary argument for static functions is simplicity. You can use them anywhere in the code without worry about creating and managing instances, dependency injection, etc. And since you aren’t creating new instances that have to be garbage collected, performance should be better as well.

That is, unless you are managing state. Then all of your static functions need to be made thread-safe, which involves potentially expensive locking and/or synchronization techniques. And even if individual calls are thread-safe, you may find the need to treat a series of calls as one atomic transaction. This is where AutoMapper enters the story.

While originally based around the use of static functions, over time AutoMapper became more and more configurable. And with each new configuration option, more state had to be managed and more potential threading issues arose. So back in January, Jimmy Bogard marked the static functions in AutoMapper 4.2 as obsolete with the intention of eventually removing them.

As I work towards the 4.2 release of AutoMapper, I got a little inspiration. Over the past year or so I’ve given some talks/podcasts about a long-lived open source codebase. One of my biggest regrets was that I made AutoMapper have a static API from literally the very beginning. The first tests/prototypes of AutoMapper all started out with “Mapper.CreateMap” and “Mapper.Map”. I showed my boss, Jeffrey Palermo, at the time and asked what he thought, and he said “looks great Jimmy, maybe you shouldn’t make it static” and I said “PFFFFFFFFFFFT NO WAY”.

Well, I’ve seen the problems with static and I’ve regretted it ever since. With the upcoming release, I’ve had a chance to prototype what it might look like without static – it worked great – and I’m ready to mark the entire static API as obsolete.

This change does pose some problems. One of the features of AutoMapper is its support for a fluent API that works with LINQ expression chains. This feature requires the use of extension methods, which are always defined as static functions.

The work around is to continue offering LINQ support, but in a way that doesn’t require the use of global state. Instead, you pass in the AutoMapper configuration info to the LINQ expression. It is a bit more verbose, but in some ways more flexible.

Here is an example from the Migrating from static API guide.

public class ProductsController : Controller {
    public ProductsController(MapperConfiguration config) {
        this.config = config;
    }
    private MapperConfiguration config;

    public ActionResult Index(int id) {
        var dto = dbContext.Products
                               .Where(p => p.Id == id)
                               .ProjectTo(config)
                               .SingleOrDefault();

        return View(dto);
    }    
}

A month later, Jimmy Bogard decided to restore the static functions. He writes,

The big pain from the static API was that the configuration could be changed at any time, and I couldn’t enforce a clear configuration step. Thinking about it, there was really nothing wrong with having a static API but just forcing you to initialize before mapping. That’s what will be allowed going forward – the instance API is now completely flushed out, and the static API is truly a thin veneer on top of it, where you call a static Initialize method instead of a constructor.

This release removes some of the obsolete attributes and restores the LINQ projections that use the static configuration.

InfoQ asks, what is your stance on the use of stateful static functions versus only allowing instance methods?

Rate this Article

Relevance
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Non-static is the way to go by wakin imgen

That's a no-brainer

Static is a design flaw by Cameron Purdy

Not the use of static, but the concept of static itself. It is a non-composable concept, and is as code-smelly as global variables were in the 80s.

Thumb rule by Binoj Antony

All methods that do not use instance variables should be marked as static

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

3 Discuss
General Feedback
Bugs
Advertising
Editorial
Marketing
InfoQ.com and all content copyright © 2006-2016 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT

We notice you’re using an ad blocker

We understand why you use ad blockers. However to keep InfoQ free we need your support. InfoQ will not provide your data to third parties without individual opt-in consent. We only work with advertisers relevant to our readers. Please consider whitelisting us.