自动映射错误,表示映射器未初始化

时间:2016-12-22 13:30:04

标签: c# asp.net-mvc automapper

我正在使用Automapper 5.2。我用作基础this链接。我将逐步描述设置我经历过的Automapper的过程。

首先我按照指示将Automapper添加到Project.json:

PM> Install-Package AutoMapper

第二次我创建了一个文件夹,用于保存与映射有关的所有文件" Mappings"

第三次我在自己的mappings文件夹文件中设置了Automapper的配置:

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

Forth 同样在mappings文件夹中的自己的文件中,我按如下方式设置了映射配置文件:

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)));
    }
}

第五,我在mappings文件夹中添加了一个扩展方法作为自己的文件...这在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());
    }
}

第六我将此行添加到Startup.cs中的ConfigureServices方法

        // Automapper Configuration
        services.AddAutoMapper();

最后我在控制器中使用它来转换集合......

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

基于我之前提到的问题,我认为我已经设置了所有内容,所以我可以使用它但是我在控制器上面的行上出现错误...

  

&#34; Mapper未初始化。使用适当的配置调用Initialize。如果您尝试通过容器或其他方式使用映射器实例,请确保您没有对静态Mapper.Map方法的任何调用,并且如果您正在使用ProjectTo或UseAsDataSource扩展方法,请确保传入适当的IConfigurationProvider实例。&#34;

我错过了什么..这是设置Automapper的正确方法吗?我怀疑我在这里错过了一步......任何帮助都非常感激。

3 个答案:

答案 0 :(得分:26)

AutoMapper有两个用法:依赖注入和旧的静态用于向后兼容。您正在为依赖注入配置它,但随后尝试使用静态。这是你的问题。你只需要选择一种方法或另一种方法。

如果你想通过依赖注入来实现它,你的控制器应该将mapper作为构造函数参数保存给成员,然后你需要使用该成员进行映射:

public class FooController : Controller
{
    private readonly IMapper mapper;

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

然后:

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

对于静态方法,您需要使用您的配置初始化AutoMapper:

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

然后你只需要在Startup.cs中调用这个方法;你将不再注册单身人士。

答案 1 :(得分:0)

更好的解决方案是创建这样的扩展方法

  public static DestinationType CastObject<SourceType, DestinationType>(this SourceType obj)
            {
                var config = new MapperConfiguration(cfg =>
                cfg.CreateMap<SourceType, DestinationType>());

                var mapper = config.CreateMapper();

                var entity = mapper.Map<DestinationType>(obj);

                return entity;
            }

答案 2 :(得分:0)

从autoMapper的V9.0开始,静态API不再可用。 或者您可以从NuGet Package Manager将版本更改为6.2.2 请参阅此文档confgiration AutoMapper