0

I went through several issues but can't get it right.

When trying to use AutoMapper 7.0, I'm getting a Mapper not initialized exception - though I think that my issue is not related to AutoMapper but to the way I try to register a service to my WCF.

I followed this article and created a ServiceBehavior for my AutoMapper:

public sealed class AutomapServiceBehavior : Attribute, IServiceBehavior
    {
        public AutomapServiceBehavior()
        {
        }


        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
            Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {
            AutomapBootstrap.InitializeMap();
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
        {

        }

        public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
        {

        }
 }

Then added a breakpoint to AutomapBootstrap.InitializeMap() (which looks like this):

public class AutomapBootstrap
    {
        public static void InitializeMap()
        {
            //BREAKPOINT ADDED HERE
            var config = new MapperConfiguration(cfg =>
               cfg.CreateMap<ClassA, ClassB>()
            );
            var mapper = new Mapper(config);

        }
    }

I thought that the app should stop at my breakpoint during startup, but it doesn't. What am I missing?

noamyg
  • 2,747
  • 1
  • 23
  • 44

1 Answers1

1

First off you need to make sure you add the Annotation to your service to call the behavior in the first place

[AutomapServiceBehavior]  <-------
[ServiceErrorBehavior(typeof(ElmahErrorHandler))]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class DVDService : IDVDService
{

Secondly the way you initialize the mapper you assign it to a var then your initialize finishes so the var will fall out of scope and be garbage collected right out the gate, even in the example in that article i doubt he tested it because his initialize doesn't call the proper method to store the mapper anywhere.

Before 9.0 you would initialize it like

 Mapper.Initialize(cfg =>
 {
     cfg.CreateMap<ClassA, ClassB>();
 });
 Mapper.AssertConfigurationIsValid();

This will store a static copy of the mapper in the run-time that can be accessed statically anywhere in the system, typically you would call this in your startup not in a service definition as it only needs to be run once. That way you don't need to call it in the service definition at all. And it's available throughout your application. And you just call it like

var result = Mapper.Map<ClassB>(classA);

After 9.0 they removed the static API and you need to use dependency injection, or you can just look at my answer at How to use AutoMapper 9.0.0 in Asp.Net Web Api 2 without dependency injection? to see how you can get around that.

Ben Walters
  • 265
  • 3
  • 4