Skip to content

Jimmy Bogard
Syndicate content
Strong opinions, weakly held
Updated: 3 hours 37 min ago

AutoMapper 4.2.0 released

Thu, 01/28/2016 - 18:28

Yesterday I bit the bullet and pushed out the 4.2.0 release. This was a fairly large internal refactoring, with the entire static API marked as obsolete and a new instance-based API exposed. Some helpful links for the move:

Some interesting things in this release that you might have missed:

It’s been a long journey with this static API, but its time is near the close. In the 5.0 release, the entire static API will be removed, making me quite happy.

Enjoy!

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs

Removing the static API from AutoMapper

Thu, 01/21/2016 - 22:19

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 is a huge shift in AutoMapper, not so much the API, but forcing everything to be static. Here’s the before:

Mapper.CreateMap<Source, Dest>();

var source = new Source();
var dest = Mapper.Map<Source, Dest>(source);

Or if you’re doing things the Right Way™ you used Initialize:

Mapper.Initialize(cfg => {
  cfg.CreateMap<Source, Dest>();
});

var source = new Source();
var dest = Mapper.Map<Source, Dest>(source);

There are a number of issues with this approach, most of which just result from having a static API. The static API was just a wrapper around instances, but the main API was all static.

With 4.2, you’ll be able to, and encouraged, to do this:

var config = new MapperConfiguration(cfg => {
  cfg.CreateMap<Source, Dest>();
});

IMapper mapper = config.CreateMapper();
var source = new Source();
var dest = mapper.Map<Source, Dest>(source);

The IMapper interface is a lot lighter, and the underlying type is now just concerned with executing maps, removing a lot of the threading problems I was having before.

I’m keeping the existing functionality and API there, just all obsoleted. The one difficult piece will be the LINQ extensions, since those as extensions methods are inherently static. You’d have to do something like this:

var config = new MapperConfiguration(cfg => {
  cfg.CreateMap<User, UserDto>();
});

var builder = config.CreateExpressionBuilder();
var users = dbContext.Users.ProjectTo<UserDto>(builder);

It’s not exactly ideal, so I’m playing with doing something like this:

var config = new MapperConfiguration(cfg => {
  cfg.CreateMap<User, UserDto>();
});
QueryableExtensions.Factories.Configuration = () => config;
// The above two can be done once at startup

var users = dbContext.Users.ProjectTo<UserDto>();

Expressions can’t depend on any runtime values, and can be more or less explicitly tied to the configuration.

The pre-release versions of AutoMapper on MyGet now have this API, so it’s not release yet as 4.2. Before I pushed 4.2 out the door, I wanted to get some feedback.

So do you like this idea? Let me know! I’ve got a GitHub issue to track the progress: https://github.com/AutoMapper/AutoMapper/issues/1031

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs

C# 6 Feature Review: Expression-Bodied Function Members

Thu, 12/17/2015 - 23:07

In the last post, I looked at auto-property enhancements, with several comments pointing out some nicer usages. I recently went through the HtmlTags codebase, C# 6-ifying “all the things”, and auto property and expression bodied function members were used pretty much everywhere. This is a large result of the codebase being quite tightly defined, with small objects and methods doing one thing well.

Expression-bodied function members can work for both methods and properties. If you have a method with one statement, and that statement can be represented as an expression:

public string GetFullName() {
  return FirstName + " " + LastName;
}

Or a getter-only properties/indexers with a body that can be represented as an expression:

public string FormalName {
  get { return FirstName[0] + ". " + LastName; }
}

You can collapse those down into something that looks like a cross between a member declaration and a lambda expression:

public string GetFullName() => FirstName + " " + LastName;

public string FormalName => FirstName[0] + ". " + LastName;

This seems to work really well when the expression can fit neatly on one line. In my refactorings, I did have places where it didn’t look so hot:

public Accessor Prepend(PropertyInfo property)
{
  return
    new PropertyChain(new IValueGetter[] {
     new PropertyValueGetter(property), 
     new PropertyValueGetter(InnerProperty)});
}

After:

public Accessor Prepend(PropertyInfo property) => 
    new PropertyChain(new IValueGetter[] {
     new PropertyValueGetter(property), 
     new PropertyValueGetter(InnerProperty)});

If the original expression looked better on multiple lines formatted out, the new expression-bodied way will look a bit weirder as you don’t have that initial curly brace. Refactoring tools try to put everything on the one line, making it pretty difficult to understand what’s going on. However, some code I have refactored down very nicely:

public class ArrayIndexer : Accessor
{
  private readonly IndexerValueGetter _getter;

  public ArrayIndexer(IndexerValueGetter getter)
  {
    _getter = getter;
  }

  public string FieldName => _getter.Name;
  public Type PropertyType => _getter.ValueType;
  public PropertyInfo InnerProperty => null;
  public Type DeclaringType => _getter.DeclaringType;
  public string Name => _getter.Name;
  public Type OwnerType => DeclaringType;

  public void SetValue(object target, object propertyValue) => _getter.SetValue(target, propertyValue);

  public object GetValue(object target) => _getter.GetValue(target);

It was a bit of work to go through the entire codebase, so I wouldn’t recommend that approach for actual production apps. However, it’s worth it if you’re already looking at some code and want to clean it up.

Verdict: Useful often; refactor code as needed going forward

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs