使用Ninject向Automapper自定义ValueResolver注入参数

6
我正在使用automapper库将我的Model转换为ViewModel。对于每个Model,我创建一个包含CreateMap的映射的配置文件。
我想使用自定义的ValueResolver,它将从IContext中获取已登录用户的ID,因此我需要使用Ninject传递IContext的实现。
在我的配置文件类中:
Mapper.CreateMap<ViewModel, BusinessModel>()
.ForMember(dest => dest.ManagerId, opt => opt.ResolveUsing<GetManagerResolver>());

然后是我的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;
    }
}

但我收到了以下异常信息 {"Type needs to have a constructor with 0 args or only optional args\r\nParameter name: type"}

是否有任何想法让automapper使用ninject进行对象创建?

更新 我的代码添加automapper配置:

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));
        });
    }
}
2个回答

8

您可以使用ConstructedBy函数配置Automapper在调用ResolveUsing后如何创建您的GetManagerResolver

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

或者,您可以在全局范围内指定 Ninject 内核,以便在使用 Mapper.Configuration.ConstructServicesUsing 方法解析任何类型时,Automapper 可以使用它:

Mapper.Configuration.ConstructServicesUsing((type) => kernel.Get(type));

好的,现在我该如何在我的自动映射配置类中获取对“kernel”的引用?请查看我的问题更新。 - ebram khalil
第一:这现在是一个完全不同且无关的问题... 第二:有多种选择:将其作为参数传递给“Configure”存储您创建它的静态字段中的内核等。 - nemesv
有人成功地将Ninject与ConstructServicesUsing_一起使用了吗? - khorvat

3
我最终做的是创建一个 NinjectModule ,用于 Automapper ,在其中放置所有的 automapper 配置,并告诉 automapper 使用 Ninject Kernel 构造对象。以下是我的代码:
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());
        });
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接