使用 [Inject] 属性进行依赖注入的 Automapper Null

Automapper Null on Dependency Injection Using [Inject] Attribute

我有一个 class 从数据库中获取一些数据,然后使用 AutoMapper 映射数据。但是,出于某种原因,mapper 永远不会注入值,因此当我尝试使用 mapper 时出现 NullReferenceException。

public class SearchesEditReview
{
    [Inject]
    public IMapper mapper { get; set; }
        
     public async Task<ViewEvent> GetEditFromId(int id)
     {
        //unrelated code

        return new ViewEvent
                {
                    Data = timelineinfo.FirstOrDefault(),
                    Medias = media,
                    //The below line breaks, saying mapper is null
                    Subjects = mapper.Map<List<DBSubject>, List<ViewSubject>>(subjects)
                };  
     }
}

我的相关事件 Startup.cs 看起来像:

 public void ConfigureServices(IServiceCollection services)
{
      // Auto Mapper Configurations
      var mapperConfig = new MapperConfiguration(mc =>
      {
           mc.AddProfile(new MappingProfile());
      });

      services.AddHttpContextAccessor();

      IMapper mapper = mapperConfig.CreateMapper();
      services.AddSingleton(mapper);
}

让我们关注 SearchesEditReview 的构建,它似乎无法正确绑定自动映射器 属性,但它应该被正确注册。

您正在使用具有 [Inject] 属性的绑定,但这并不总是很清楚它是如何工作的(至少对我来说是这样;有大量的框架,它们的做法都略有不同)。出于这个原因,我倾向于使用构造函数注入模式:

public class SearchesEditReview
{
     public SearchesEditReview(IMapper mapper) //dependencies here
     {
        //attach to properties
     }
}

除了没有 parameter-less 构造函数的缺点之外,它还有两个优点:

  1. 你是强制传参的,所以不会有歧义,更容易调试
  2. 您独立于 DI 框架。你很少会用到。

如前所述,对于 .net Core,您可以使用 NuGet package 作为 .net Core 依赖注入框架:

Install-Package AutoMapper.Extensions.Microsoft.DependencyInjections:

然后像这样注册:

public void ConfigureServices(IServiceCollection services)
{
    //...
    //You'll need to pass in the assemblies containing your profiles,
    //or the profiles itself
    services.AddAutoMapper(typeof(YourProfile1),typeof(YourProfile2)); //etc
}

注意: 有时使用加载程序集扫描 GetAssemblies 可能容易出错。由于这发生在启动时,可能尚未加载包含程序集的配置文件。

有关详细信息,请参阅 this blog post or this documentation


另请记住,您需要确保框架能够构建 SearchesEditReview

你不能像那样注入 class。但是,您使用的语法在 .razor 页面上可以正常工作。 请参阅 docs

改变你的class。注意构造函数。

public class SearchesEditReview
{
    public SearchesEditReview(IMapper mapper)
    {
        this.mapper = mapper;
    }
       
    IMapper mapper { get; set; }

    public async Task<ViewEvent> GetEditFromId(int id)
    {
        //unrelated code

        return new ViewEvent
        {
            Data = timelineinfo.FirstOrDefault(),
            Medias = media,
            //The below line breaks, saying mapper is null
            Subjects = mapper.Map<List<DBSubject>, List<ViewSubject>>(subjects)
        };
    }
}

Startup.cs

...
services.AddSingleton(mapper);
services.AddSingleton<SearchesEditReview>();