GlobalJim
GlobalJim

Reputation: 1189

How to use AutoMapper 9.0.0 in Asp.Net Web Api 2 without dependency injection?

I haven't been able to find any info where to put this code inside my project. Right now I am use using this in each action I need the mapper. Is there a better way to do this with out dependency injection?

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


            var destList= iMapper.Map<Dest[]>(sourceList);

Upvotes: 2

Views: 5206

Answers (1)

Ben Walters
Ben Walters

Reputation: 275

Dependency injection added a whole level of complexity to my legacy project that I just didn't want to deal with. 9.0 removed the api to call it staticly.

So I just reverse engineered what it was doing in 8.0 and wrote a wrapper for it.

public static class MapperWrapper 
{
    private const string InvalidOperationMessage = "Mapper not initialized. Call Initialize with appropriate configuration. If you are trying to use mapper instances through a container or otherwise, make sure you do not have any calls to the static Mapper.Map methods, and if you're using ProjectTo or UseAsDataSource extension methods, make sure you pass in the appropriate IConfigurationProvider instance.";
    private const string AlreadyInitialized = "Mapper already initialized. You must call Initialize once per application domain/process.";

    private static IConfigurationProvider _configuration;
    private static IMapper _instance;

    private static IConfigurationProvider Configuration
    {
        get => _configuration ?? throw new InvalidOperationException(InvalidOperationMessage);
        set => _configuration = (_configuration == null) ? value : throw new InvalidOperationException(AlreadyInitialized);
    }

    public static IMapper Mapper
    {
        get => _instance ?? throw new InvalidOperationException(InvalidOperationMessage);
        private set => _instance = value;
    }

    public static void Initialize(Action<IMapperConfigurationExpression> config)
    {
        Initialize(new MapperConfiguration(config));
    }

    public static void Initialize(MapperConfiguration config)
    {
        Configuration = config;
        Mapper = Configuration.CreateMapper();
    }

    public static void AssertConfigurationIsValid() => Configuration.AssertConfigurationIsValid();
}

To initialize it have a configure method

public static class AutoMapperConfig
{
    public static void Configure()
    {
        MapperWrapper.Initialize(cfg =>
        {
            cfg.CreateMap<Foo1, Foo2>();              
        });

        MapperWrapper.AssertConfigurationIsValid();
    }
}

And just call it in your startup

AutoMapperConfig.Configure();

To use it just Add MapperWrapper before your Mapper call. Can be called anywhere.

 MapperWrapper.Mapper.Map<Foo2>(Foo1);

Upvotes: 11

Related Questions