ASP.NET Core 2.2:无法解析类型为'AutoMapper.IMapper'的服务

Gon*_*ica 3 c# api asp.net-core-mvc .net-core asp.net-core

ASP.NET Core(版本:2.2.102)

I am building an API to return Portos and Especies, but anytime that I access /api/portos (as defined in the controller), I get this error:

InvalidOperationException: Unable to resolve service for type 'AutoMapper.IMapper' while attempting to activate 'fish.Controllers.PortosController'.

Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, bool isDefaultParameterRequired)

I am not sure what am I doing wrong, so any help is appreciated.


Models


Especie.cs

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace fish.Models
{
    [Table("Especies")]
    public class Especie
    {
        public int Id { get; set; }
        [Required]
        [StringLength(255)]
        public string Nome { get; set; }

        public Porto Porto { get; set; }
        public int PortoId { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

Porto.cs

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;

namespace fish.Models
{
    public class Porto
    {
        public int Id { get; set; }
        [Required]
        [StringLength(255)]
        public string Nome { get; set; }
        public ICollection<Especie> Models { get; set; }

        public Porto()
        {
            Models = new Collection<Especie>();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Controller


PortoController.cs

using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using fish.Controllers.Resources;
using fish.Models;
using fish.Persistence;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace fish.Controllers
{
    public class PortosController : Controller
    {
        private readonly FishDbContext context;
        private readonly IMapper mapper;
        public PortosController(FishDbContext context, IMapper mapper)
        {
            this.mapper = mapper;
            this.context = context;
        }


        [HttpGet("/api/portos")]
        public async Task<IEnumerable<PortoResource>> GetPortos()
        {
            var portos = await context.Portos.Include(m => m.Models).ToListAsync();

            return mapper.Map<List<Porto>, List<PortoResource>>(portos);
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

Controller>Resources

PortoResources.cs

using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace fish.Controllers.Resources
{
    public class PortoResource
    {
        public int Id { get; set; }
        public string Nome { get; set; }
        public ICollection<EspecieResource> Models { get; set; }

        public PortoResource()
        {
            Models = new Collection<EspecieResource>();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

EspecieResource.cs

namespace fish.Controllers.Resources
{
    public class EspecieResource
    {
        public int Id { get; set; }
        public string Nome { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

More Relevant Code


Stratup.cs

public void ConfigureServices(IServiceCollection services)
{
        services.AddAutoMapper();

        services.AddDbContext<FishDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Default")));

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

        // In production, the Angular files will be served from this directory
        services.AddSpaStaticFiles(configuration =>
        {
            configuration.RootPath = "ClientApp/dist";
        });
}
Run Code Online (Sandbox Code Playgroud)

MappingProfile.cs

using AutoMapper;
using fish.Controllers.Resources;
using fish.Models;

namespace fish.Mapping
{
    public class MappingProfile : Profile
    {
        public MappingProfile()
        {
            CreateMap<Porto, PortoResource>();
            CreateMap<Especie, EspecieResource>();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

FishDbContext.cs

using fish.Models;
using Microsoft.EntityFrameworkCore;

namespace fish.Persistence
{
    public class FishDbContext : DbContext
    {
        public FishDbContext(DbContextOptions<FishDbContext> options) : base(options)
        {

        }

        public DbSet<Porto> Portos { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

Man*_*ari 11

You will have to use automapper package as shown below:

Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection
Run Code Online (Sandbox Code Playgroud)

This will also in turn install the Automapper nuget package if you don’t have it already.

Then, inside your ConfigureServices method of your startup.cs, you will have to add a call to it as shown below.

public void ConfigureServices(IServiceCollection services)
{
    services.AddAutoMapper();
}
Run Code Online (Sandbox Code Playgroud)

Refer this blog for more details.

EDIT:

There is very nice description from this thread.

You need to add code like below in startup.cs.

You have missed to add IMapper in DI. Please refer add Singleton call from below code.

public void ConfigureServices(IServiceCollection services) {
    // .... Ignore code before this

   // Auto Mapper Configurations
    var mappingConfig = new MapperConfiguration(mc =>
    {
        mc.AddProfile(new MappingProfile());
    });

    IMapper mapper = mappingConfig.CreateMapper();
    services.AddSingleton(mapper);

    services.AddMvc();

}
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的时间。我已经添加了那个包。检查Startup.cs (2认同)
  • 更新了答案,希望这可以帮助您解决问题。 (2认同)
  • `IMapper` 应该是有范围的,而不是单例 (2认同)
  • 自从我开始一个新项目以来,需要一分钟,并且需要包含AutoMapper。添加服务时出现了折旧警告。AddAutoMapper(); 到startup.cs。您编辑的答案非常有帮助。谢谢! (2认同)

msp*_*c96 7

如果您使用 .NET CORE 5。首先转到 nuget 包,找到并安装 AutoMapper.Extensions.Microsoft.DependencyInjection在此输入图像描述

然后您应该从 Automapper 扩展 Profile 并为您的类编写映射。像下面这样的东西在此输入图像描述 然后,您应该在Startup类的ConfigureServices方法中添加Automapper。如果您的AutoMapper的nuget包与映射配置文件类位于同一项目中,则可以省略此typeof(CommonMappingProfile)。

 services.AddAutoMapper(typeof(CommonMappingProfile));
Run Code Online (Sandbox Code Playgroud)

  • 这是我的代码的图片,所以基本上是相似的 (2认同)