Professional Documents
Culture Documents
Archive
Tags
Find an article Search
About
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 rst tests/prototypes of AutoMapper all started out with
“Mapper.CreateMap” and “Mapper.Map”. I showed my boss, Je rey 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:
1 Mapper.CreateMap<Source, Dest>();
2
3 var source = new Source();
4 var dest = Mapper.Map<Source, Dest>(source);
1 Mapper.Initialize(cfg => {
2 cfg.CreateMap<Source, Dest>();
3 });
4
https://lostechies.com/jimmybogard/2016/01/21/removing-the-static-api-from-automapper/ 1/13
8/27/2020 Removing the static API from AutoMapper · Los Techies
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.
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 di cult
piece will be the LINQ extensions, since those as extensions methods are inherently
static. You’d have to do something like this:
It’s not exactly ideal, so I’m playing with doing something like this:
https://lostechies.com/jimmybogard/2016/01/21/removing-the-static-api-from-automapper/ 2/13
8/27/2020 Removing the static API from AutoMapper · Los Techies
Authors
Andrew Siemer
Chad Myers
Chris Missal
Chris Patterson
Derek Greer
Derik Whittaker
Eric Anderson
Eric Hexter
Gabriel Schenker
Gregory Long
Hugo Bonacci
James Gregory
Jason Meridth
Jimmy Bogard
John Teague
Josh Arnold
Joshua Flanagan
Joshua Lockwood
Keith Dahlby
Matt Hinze
Patrick Lioi
Rod Paddock
Ryan Rauh
Ryan Svihla
Scott Densmore
Sean Biefeld
Sean Chambers
Sharon Cichelli
Steve Donie
https://lostechies.com/jimmybogard/2016/01/21/removing-the-static-api-from-automapper/ 12/13
8/27/2020 Removing the static API from AutoMapper · Los Techies
https://lostechies.com/jimmybogard/2016/01/21/removing-the-static-api-from-automapper/ 13/13
8/27/2020 Removing the static API from AutoMapper · Los Techies
Expressions can’t depend on any runtime values, and can be more or less explicitly tied
to the con guration.
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
Sponsored
Mereka Yang Lahir Antara Tahun 1941 dan 1981 Memenuhi Syarat untuk Survei dengan Bayaran
Tinggi
Survey Com pare
MediatR Extensions for Micro AutoMapper 5.0 Beta release New Yea
4 years ago • 9 comments 4 years ago • 7 comments 4 years ago • 15 comments 4 years a
To help those building We’ve been using MediatR This week marks a huge One of m
applications using the new (or some manifestation of it) milestone in AutoMapper- year was
Microsoft DI libraries … for a number of years … land, the beta release of … of my dig
LOG IN WITH
OR SIGN UP WITH DISQUS ?
Name
https://lostechies.com/jimmybogard/2016/01/21/removing-the-static-api-from-automapper/ 3/13
8/27/2020 Removing the static API from AutoMapper · Los Techies
Name
I think the reason static methods took off as a style was because of Linq
and extension methods that came with it. The only problem was that people (I know I did) wrote
extension methods (a very functional style) as if they were instance methods (very OO style),
and I guess would get caught in some traps that I just don't see in F#, such as threading issues.
Best practices I've tried to follow. Taken from guru's like Scott Wlaschin, Tomas Petricek, Jon
Skeet
F# Best Practice 1) Try to make most things immutable, goal being everything is immutable.
F# Best Practice 2) If it is mutable make it explicit, big warning flags (in F# this would usually be
.NET Properties)
F# Best Practice 3) Treat your functions as input and output, no side effects, do only one thing. In
the end you could almost substitute it with a table of values or dictionary of precalculated/cached
values.
String does this, Linq does this. You call .ToUpper or .Where, you get a new thing, you don't
modify the original. At first it was weird, then overtime we came to enjoy the features of this and
but may not have known why.
I think there are other ways around this, like what you're proof of concept is doing, closures or
functions that create functions to create your thing.
3△ ▽ • Reply • Share ›
Basically with the old static interface, one would simply call
Mapper.CreateMap (with optional mapping config) *for each pair of objects
(source/destination)* that you'd want to map, essentially registering the
mapper internally (the "teaching" part to which I referred). Then, you'd just
call Mapper.Map(source) and so long as you created the map beforehand,
you'd be good. But since Mapper.CreateMap() has been removed, I'm not
sure how to register all of the mappers, as the Initialize() method only
seems to take a single expression which is why I'm asking how would
https://lostechies.com/jimmybogard/2016/01/21/removing-the-static-api-from-automapper/ 5/13
8/27/2020 Removing the static API from AutoMapper · Los Techies
seems to take a single expression -- which is why I m asking how would
one CreateMap for multiple objects.
Mapper.Initialize(cfg =>
{
cfg.CreateMap<test1a, test1b="">();
cfg.CreateMap<test2a, test2b="">();
});
I think I just came to that realization. Feels a little awkward because it's
referred to as an expression rather than a delegate (I guess I took it literally
and was thinking of it like a MemberExpression for whatever reason); I was
comparing it to the old interface, but i'll buy it. Can I recommend showing
that as an example in the Getting Started doc?
△ ▽ • Reply • Share ›
I just found out about AutoMapper but cannot figure out in my MVC5 application where to place
configuration code (startup.cs? global.asax?) and how to properly use AutoMapper to map the
results of an EF LINQ query results to a viewmodel which gets send to a view in the Return View
statement... I desperately wanna get out of matching field for field ..
Any chance you can help out a newbie to this? I need to know where in Donald Trump (sorry for
the swearing) I'm supposed to place my code...
1△ ▽ • Reply • Share ›
Can you point me to a good code sample that maps a model to a Viewmodel and
how it is initialized at application start and used within a controller? There are
many partial examples that "assume" we know where stuff goes... I'd prefer doing
it the "new" way... so I don't have to change much when going to V5...
△ ▽ • Reply • Share ›
Now how do I do mapping once per application? Do I need to create map before I do mapping
every time? What is project structure for new approach?
△ ▽ • Reply • Share ›
If I want to go from CategoryModel to Category and CategoryModel has no value in Property "Id", it
should keep the Id of the original Category.
category should be Id = 2 and Name "b". It ignores the "Id" of model because it came null, so It
should keep the original value.
Thanks!
△ ▽ • Reply • Share ›
https://lostechies.com/jimmybogard/2016/01/21/removing-the-static-api-from-automapper/ 9/13
8/27/2020 Removing the static API from AutoMapper · Los Techies
The syntax is a little nastier than the extension methods, but this would allow using different
mapping profiles in different places of the application. (Not sure why you'd need that though)
△ ▽ • Reply • Share ›
But I often chain after the Select too, so that syntax would be awkward.
△ ▽ • Reply • Share ›
---
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<user, userdto="">();
});
Since the configuration is done at startup, how would you tell the extension
method which mapping profile or configuration it would need to use?
PS: I've started using automapper a few moths ago, and i fell in love with it
immediately, so thanks for building this awesome framework :)
EDIT: Now that i think about it, i guess using the first approach, one could register
expression builders for each tenant, and inject the expression builder on your
service/query/command/whatever
△ ▽ • Reply • Share ›
Speaking of which, a random thought I had just now, but maybe a new best practice for all
obsolete/deprecated messages should include a URL if possible? That would be pretty
rad/convenient.
△ ▽ • Reply • Share ›
https://lostechies.com/jimmybogard/2016/01/21/removing-the-static-api-from-automapper/ 10/13
8/27/2020 Removing the static API from AutoMapper · Los Techies
It looks like this approach would eliminate that completely, and let me scope configs/IMappers
only as much as I needed to, without worrying what my dependencies may or may not be doing.
△ ▽ • Reply • Share ›