【问题标题】:AutoMapperMappingException when using ConstructUsingServiceLocator() in ASP.NET Core 2.1在 ASP.NET Core 2.1 中使用 ConstructUsingServiceLocator() 时出现 AutoMapperMappingException
【发布时间】:2018-08-22 11:18:05
【问题描述】:

我在我的 ASP.NET Core 2.1 Web 应用程序中使用 AutoMapper 7.0.1 和 AutoMapper.Extensions.Microsoft.DependencyInjection 5.0.1。当我映射到未配置ConstructUsingServiceLocator() 的类型时,映射有效。当我映射到使用ConstructUsingServiceLocator() 配置的类型时,它会抛出以下内容:

AutoMapperMappingException: Cannot create an instance of type 
AutoMapperTest.Destination
AutoMapper.MappingOperationOptions<TSource, TDestination>.CreateInstance<T>() in MappingOperationOptions.cs, line 47

我正在遵循此处给出的将 AutoMapper 与 ASP.NET Core 结合使用的最新指南:How to pass a service from .net core di container to a new object created with automapper

我在一个全新的项目中用一个最小的例子复制了这个。以下是相关部分:

新建项目 > APS.NET Core Web 应用程序 > Web 应用程序

安装 AutoMapper 7.0.1 和 AutoMapper.Extensions.Microsoft.DependencyInjection 5.0.1 Nuget 包。

来源:

public class Source
{
    public string Name { get; set; }
}

目的地:

public class Destination
{
    private readonly IDestinationRepository _repo;

    public Destination(IDestinationRepository repo)
    {
        _repo = repo ?? throw new ArgumentNullException(nameof(repo));
    }

    public string Name { get; set; }
}

IDestinationRepository:

public interface IDestinationRepository
{
}

目标存储库:

public class DestinationRepository : IDestinationRepository
{
}

映射配置文件:

public class MappingProfile : Profile
{
    public MappingProfile()
    {           
        CreateMap<Source, Destination>().ConstructUsingServiceLocator();
    }
}

Startup.ConfigureServices(IServiceCollection 服务):

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IDestinationRepository, DestinationRepository>();

    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

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

    services.AddAutoMapper();
}

索引模型:

public class IndexModel : PageModel
{
    private readonly IMapper _mapper;

    public IndexModel(IMapper mapper)
    {
        _mapper = mapper;
    }

    public void OnGet()
    {
        _mapper.ConfigurationProvider.AssertConfigurationIsValid();            // <- Succeeds
        var repo = _mapper.ServiceCtor.Invoke(typeof(IDestinationRepository)); // <- repo is non-null

        var source = new Source {Name = "Test"};
        var destination = _mapper.Map<Source, Destination>(source);            // <- Fails!!
    }
}

上述在_mapper.Map&lt;Source, Destination&gt;(source) 调用中失败,但上面列出的例外情况。我已验证 MappingProfile 正在加载。

如果我将Destination ctor 更改为无参数,它仍然会失败。

但是,如果我从MappingProfile 中删除ConstructUsingServiceLocator()(带有空的Destination ctor),我的映射就会开始工作。

我在这里做错了什么?感谢您的帮助!

【问题讨论】:

  • 我猜:您的 Destination 类未在 di 中注册,因此无法让 di 创建 Destination 的新实例。
  • 就是这样!如果我在启动配置中添加services.AddTransient&lt;Destination, Destination&gt;();,映射就会开始工作。我没想到必须这样做——我过去使用过的 DI 容器不需要显式注册具体类型,而且我没有意识到 ASP.NET Core 容器确实需要。事实上,在考虑了 ASP.NET Core 容器(stackoverflow.com/questions/30681477/…)的一些限制之后,我可能会切换到第三方容器。
  • @christoph-lütjen - 添加您的评论作为答案,我会感谢您解决我的问题。谢谢!
  • 很高兴,感谢您的反馈

标签: c# asp.net-core automapper asp.net-core-2.1


【解决方案1】:

您的Destination 类未在di 容器中注册,因此无法让di 容器创建Destination 类的新实例。

【讨论】:

    猜你喜欢
    • 2019-05-06
    • 2020-02-17
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    • 2020-03-26
    • 2019-04-18
    • 2019-02-10
    • 2019-02-19
    相关资源
    最近更新 更多