web-dev-qa-db-fra.com

Erreur Automapper en disant que le mappeur n'est pas initialisé

J'utilise Automapper 5.2. J'ai utilisé comme base this link. Je vais décrire, par étapes, le processus de configuration d’Automapper que j’ai suivi.

First J'ai ajouté Automapper à Project.json comme indiqué:

PM> Install-Package AutoMapper

Second J'ai créé un dossier contenant tous les fichiers relatifs au mapping appelé "Mappings"

Third J'ai configuré la configuration de Automapper dans son propre fichier dans le dossier mappings:

public class AutoMapperConfiguration
{
    public MapperConfiguration Configure()
    {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile<ViewModelToDomainMappingProfile>();
            cfg.AddProfile<DomainToViewModelMappingProfile>();
            cfg.AddProfile<BiDirectionalViewModelDomain>();
        });
        return config;
    }
}

Forth Également dans son propre fichier dans le dossier Mappings, je configure le profil de mappage comme suit:

public class DomainToViewModelMappingProfile : Profile
{
    public DomainToViewModelMappingProfile()
    {
        CreateMap<Client, ClientViewModel>()
           .ForMember(vm => vm.Creator, map => map.MapFrom(s => s.Creator.Username))
           .ForMember(vm => vm.Jobs, map => map.MapFrom(s => s.Jobs.Select(a => a.ClientId)));
    }
}

Fifth, j'ai ajouté une méthode d'extension en tant que son propre fichier également dans le dossier mappings ... ceci a ensuite été utilisé dans startup.cs:

public static class CustomMvcServiceCollectionExtensions
{
    public static void AddAutoMapper(this IServiceCollection services)
    {
        if (services == null)
        {
            throw new ArgumentNullException(nameof(services));
        }
        var config = new AutoMapperConfiguration().Configure();
        services.AddSingleton<IMapper>(sp => config.CreateMapper());
    }
}

Sixth J'ai ajouté cette ligne à la méthode ConfigureServices dans Startup.cs

        // Automapper Configuration
        services.AddAutoMapper();

Enfin, je l'ai utilisé dans un contrôleur pour convertir une collection ...

 IEnumerable<ClientViewModel> _clientVM = Mapper.Map<IEnumerable<Client>, IEnumerable<ClientViewModel>>(_clients);

Sur la base de la question à laquelle j'ai fait référence précédemment, je pensais avoir tout configuré pour pouvoir l'utiliser, mais j'ai eu une erreur sur la ligne ci-dessus dans le contrôleur ...

"Mappeur non initialisé. Appelez Initialiser avec la configuration appropriée. Si vous essayez d'utiliser des instances de mappeur via un conteneur ou autrement, assurez-vous de ne pas avoir d'appels aux méthodes statiques Mapper.Map, et si vous utilisez ProjectTo ou UseAsDataSource méthodes d’extension, assurez-vous de transmettre l’instance IConfigurationProvider appropriée. "

Qu'est-ce que j'ai manqué? Est-ce la bonne façon de configurer Automapper? Je soupçonne que je manque une étape ici .. toute aide grandement appréciée.

13
si2030

AutoMapper a deux usages: l'injection de dépendance et l'ancien statique pour la compatibilité descendante. Vous le configurez pour l'injection de dépendance, mais essayez ensuite d'utiliser le statique. C'est ton problème. Vous devez juste choisir une méthode ou une autre et y aller.

Si vous souhaitez le faire avec une injection de dépendance, votre contrôleur doit prendre le mappeur en tant qu'argument de constructeur, en le sauvegardant dans un membre. Vous devrez ensuite utiliser ce membre pour effectuer votre mappage:

public class FooController : Controller
{
    private readonly IMapper mapper;

    public FooController(IMapper mapper)
    {
        this.mapper = mapper;
    }

Ensuite:

IEnumerable<ClientViewModel> _clientVM = mapper.Map<IEnumerable<Client>, IEnumerable<ClientViewModel>>(_clients);

Pour la méthode statique, vous devez initialiser AutoMapper avec votre configuration:

public MapperConfiguration Configure()
{
    AutoMapper.Mapper.Initialize(cfg =>
    {
        cfg.AddProfile<ViewModelToDomainMappingProfile>();
        cfg.AddProfile<DomainToViewModelMappingProfile>();
        cfg.AddProfile<BiDirectionalViewModelDomain>();
    });
}

Il suffit ensuite d’appeler cette méthode dans Startup.cs; vous ne voudriez plus enregistrer le singleton.

20
Chris Pratt

Je reçois cette erreur avec AutoMapper.Extensions.Microsfot.DependencyInjection Version 5.0.1 et AutoMapper 7.0.1. L'installation de 3.2.0 avec AutoMapper 6.1.1 corrige le problème et appelons _mapper.Map normalement. Je ne sais pas pourquoi, autant que je sache, je n'appelle pas la classe statique Mapper et je n'utilise pas ProjectTo ou UseAsDataSource.

0
MDave