TransWikia.com

Automapper Null on Dependency Injection Using [Inject] Attribute

Stack Overflow Asked on January 24, 2021

I have a class that fetches some data from a database and I then map the data using AutoMapper. However, for some reason, mapper never gets a value injected so I get a NullReferenceException when I try to use mapper.

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

My relevent Startup.cs looks like:

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

2 Answers

You cannot Inject into a class like that. The syntax your using would work fine on a .razor page however. Please see docs

Change your class. Note the constructor.

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

Correct answer by Brian Parker on January 24, 2021

Lets focus on the construction of SearchesEditReview, which seems to be unable to correctly bind the automapper property, while it's should be registered correctly.

You are using a binding with an [Inject] attribute, but that's not always clear how it works (well at least to me; there are ton's of frameworks, all doing it a little differently). For this reason I tend to use the constructor injection pattern:

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

Next to the downside of don't having a parameter-less constructor, it has 2 advantages:

  1. you are forced to pass the parameter, so there will be no ambiguity, it is easier to debug
  2. You're independent of the DI framework. Which you'll seldom use.

As mentioned, for .net Core you can use a NuGet package for the .net Core Dependency Injection Framework:

Install-Package AutoMapper.Extensions.Microsoft.DependencyInjections:

And register like this:

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
}

Note: The sometimes used loaded assembly scan GetAssemblies can be error prone. Since this occurs at startup, profile containing assemblies might not be loaded yet.

See this blog post or this documentation for more details.


Also keep in mind that you need to make sure the framework is able to construct SearchesEditReview.

Answered by Stefan on January 24, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP