Inject parameter into automapper custom ValueResolver using Ninject
Asked Answered
N

2

6

I'm using automapper library to convert my Model into my ViewModel. For each Model, I create profile which inside i add my maps using CreateMap.

I want to use custom ValueResolver in which it will get the logged user ID from IContext, so i need to pass implementation of IContext using Ninject.

Inside my profile class:

Mapper.CreateMap<ViewModel, BusinessModel>()
.ForMember(dest => dest.ManagerId, opt => opt.ResolveUsing<GetManagerResolver>());

Then my GetManagerResolver:

public class GetManagerResolver : ValueResolver<BusinessModel, int>
{
    private IContext context;
    public GetManagerResolver(IContext context)
    {
        this.context = context;
    }

    protected override int GetManagerResolver(BusinessModel source)
    {
        return context.UserId;
    }
}

But i get this exception message {"Type needs to have a constructor with 0 args or only optional args\r\nParameter name: type"}.

Any Ideas on how make automapper use ninject for object creation?

UPDATE My code to add automapper configuration:

public static class AutoMapperWebConfiguration
{
    public static void Configure()
    {
        Mapper.Initialize(cfg =>
        {            
            cfg.AddProfile(new Profile1());         
            cfg.AddProfile(new Profile2());

            // now i want to add this line, but how to get access to kernel in static class?
            // cfg.ConstructServicesUsing(t => Kernel.Get(t));
        });
    }
}
Nole answered 30/6, 2014 at 15:53 Comment(0)
V
8

You can use the ConstructedBy function to configure how Automapper should create your GetManagerResolver after calling ResolveUsing:

Mapper.CreateMap<ViewModel, BusinessModel>()
    .ForMember(dest => dest.ManagerId, 
         opt => opt.ResolveUsing<GetManagerResolver>()
                   .ConstructedBy(() => kernel.Get<GetManagerResolver>());

Or you can globally sepecify your Ninject kernel to be used by Automapper when resolving any type with Mapper.Configuration.ConstructServicesUsing method:

Mapper.Configuration.ConstructServicesUsing((type) => kernel.Get(type));
Variscite answered 1/7, 2014 at 5:44 Comment(3)
Good, now how can i get refrence to kernel inside my automapper configuration class? see my question updateNole
First: This is now a completely different and unrealted question... Second: there are multiple options: pass it in as parameter to Configure store your Kernel in a static field where you create it, etc.Variscite
Did anyone managed to get Ninject working with the ConstructServicesUsing_ ?Peper
N
3

What I ended up doing was to create NinjectModule for Automapper where I put all my automapper configuration and tell automapper to use Ninject Kernel to construct objects. Here is my code:

public class AutoMapperModule : NinjectModule
{
    public override void Load()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.ConstructServicesUsing(t => Kernel.Get(t));

            cfg.AddProfile(new Profile1());
            cfg.AddProfile(new Profile2());
        });
    }
}
Nole answered 7/7, 2014 at 17:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.