0

Now that AutoMapper is abolishing both the static API and the ability to change the mappings at runtime I have a problem with my WebForms application without an IoC manager.

For the sake of this question take as given I cannot introduce an IoC manager into this application, and while it would be "good to do" the application has been working fine without it for a number of years, and it cannot be done right at the moment. In the future maybe, but not now.

With AutoMapper what I used to do before was have a method in each class I instantiated that was called automatically by the constructor. In that method I would have the necessary:

Mapper.CreateMap<>()

calls. This has the following advantages:

  • I only mapped what I needed per request (and depending on program flow this list of mappings would grow to what I needed)
  • All types were "local" - meaning I did not have to reference other projects in the solution

I was happy to live with the performance hit each request of doing things this way instead of doing this once in Application_Start().

However with AutoMapper 5... Having read migrating from the static API it appears that I now have to:

  1. Do all the mappings "somewhere" where I have access to all the types I want to map. So no matter where I put this I have to reference every other assembly in my solution?
  2. Having stored the MapperConfiguration() instance somewhere globally accessible - lets say either HttpContext or HttpApplication so I can call MapperConfiguration.CreateMapper() I now need to make sure that I have access to HttpContext / HttpApplication everywhere. This ultimately means projects that have no need of say the HttpContext will now need to access it.

If my assumptions in 1. & 2. above are correct I now have a big mess of tightly coupled spaghetti code.

So my question is this:

How do I use AutoMapper 5 in a webforms application with numerous projects (and hence many types) in the solution, without an IoC elegantly?

TheEdge
  • 9,291
  • 15
  • 67
  • 135

1 Answers1

5

AutoMapper isn't abolishing the static API. Just the pieces that modify configuration at will. It turns out that allowing Mapper.CreateMap at any time forces me to make mapping sloooooooow.

That wiki page I forgot to delete. Here's the actual guidance:

https://github.com/AutoMapper/AutoMapper/wiki/Static-and-Instance-API

And 5.0 upgrade guide:

https://github.com/AutoMapper/AutoMapper/wiki/5.0-Upgrade-Guide

The overall story is "get rid of your Mapper.CreateMap calls sprinkled everywhere and put them in initialization". You can use profiles to help you out.

But Mapper.CreateMap sprinkled throughout your app was ALWAYS dangerous. It meant you couldn't use Mapper.AssertConfigurationIsValid, which is very dangerous to skip. If you can't assert configuration validation, you shouldn't use AutoMapper.

Jimmy Bogard
  • 26,045
  • 5
  • 74
  • 69
  • I understand the need for the changes and embrace them for the speed improvement, enforced stability etc.. However "....put them in initialization" - In my situation (without IoC) means put it in Global.asax - Application_Start and reference every assembly in my main web application? I see no other way around this. And then furthermore I now have to have a global that I can access in every other assembly? I just want to make sure I have not missed something really obvious here. As clearly I will be making some pretty bad code smells in doing this. – TheEdge Jul 29 '16 at 04:42
  • Yes, although I don't see the problem with referencing every assembly in your main web application. Unless you're building some sort of pluggable portal, that shouldn't be a problem. Most people, however, create Profile classes in their child assemblies and put the config in there. The Mapper.Initialize call will then just add all those profiles, either manually or via reflection to scan for all Profiles. – Jimmy Bogard Jul 31 '16 at 21:05
  • Also, I'm not sure what code smells you're referring to? This is pretty much the recommended way to configure AutoMapper. – Jimmy Bogard Jul 31 '16 at 21:06
  • Assume I am doing DDD. So whereas before my main web app never had to access the assembly holding my repository classes as it always accessed the assembly holding my services (and my services were the ones that accessed the repos). Now I need to add a reference to an assembly (repos) that was never needed before. Hence code smell and tight coupling. I will look at the profiles and see if I can mitigate this. – TheEdge Jul 31 '16 at 23:28
  • 1
    Hmmm, DDD has nothing to do with project structures. That sounds like a complicated architecture with all those projects and rules. Completely off topic, but you should *really* look at my video on SOLID architecture in slices not layers. It cuts down layering cruft quite a bit https://vimeo.com/131633177. Good luck! – Jimmy Bogard Aug 01 '16 at 01:09
  • 1
    @TheEdge: as explained [here](https://stackoverflow.com/q/9501604/264697) it is quite natural to reference your assemblies from your web app. Stop trying to prevent this from happening. – Steven Aug 01 '16 at 05:17
  • Jimmy - Thanks I will have a look at the video. @Steven. Thanks for that. I am used to the module approach where things are very loosely coupled. – TheEdge Aug 01 '16 at 10:09