Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autofac + Automapper + custom ValueResolver

Let's say I have custom ValueResolver

public class AssessmentAttendiesResolver : ValueResolver<List<int>, ICollection<Expert>>
{
    private readonly IRepository<Expert> _expertRepository; 

    public AssessmentAttendiesResolver(IRepository<Expert> expertRepository)
    {
        _expertRepository = expertRepository;
    }

    protected override ICollection<Expert> ResolveCore(List<int> source)
    {
        return (ICollection<Expert>)_expertRepository.Query();
    }
}

In my Global.asax I registered my custom resolver and override Mapper.Initialize method like this.

builder.RegisterAssemblyTypes(currentAssembly).AsClosedTypesOf(typeof(ValueResolver<,>)).AsSelf();

    var container = builder.Build();
    Mapper.Initialize(conf => conf.ConstructServicesUsing(container.Resolve));

And CreateMap method

    Mapper.CreateMap<AssessmentCreateRequestModel, Assessment>()
        .ForMember(dest => dest.Attendies, opt => opt.ResolveUsing<AssessmentAttendiesResolver>().FromMember(item => item.Attendies));

When I run the code I get such exception

No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.

What should I change in order to successfully inject my repositories in my custom value resolver?

like image 502
Jevgenij Nekrasov Avatar asked Dec 06 '25 20:12

Jevgenij Nekrasov


1 Answers

You are passing container.Resolve to your Mapper.Initialize call, which means all of your services will be resolved scoped to the container's lifetime scope. But the error message indicates that it's trying to resolve some service that is registered InstancePerHttpRequest.

You need to either change the relevant registrations so that they aren't scoped to the http request, or change the lamba you're passing to Mapper.Initialize to that it resolves from the current lifetime scope.

I don't know how when Automapper resolves services and how long it holds onto them to be able to tell you which solution is better. Ideally... IF Automapper only resolves services at the moment it needs them, and then immediately forgets about them, then I would recommend using my second solution, otherwise you'll be forced to use the first solution.

like image 192
Jim Bolla Avatar answered Dec 08 '25 11:12

Jim Bolla



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!