如何在Ninject.Web.Mvc中使用AutoMapper?

建立

我有一个设置AutoMapper映射的AutoMapperConfiguration静态类:

static class AutoMapperConfiguration()
{
    internal static void SetupMappings()
    {
        Mapper.CreateMap<long, Category>.ConvertUsing<IdToEntityConverter<Category>>();
    }
}

IdToEntityConverter<T>是一个定制的ITypeConverter ,它看起来像这样:

class IdToEntityConverter<T> : ITypeConverter<long, T> where T : Entity
{
    private readonly IRepository _repo;

    public IdToEntityConverter(IRepository repo)
    {
        _repo = repo;
    }

    public T Convert(ResolutionContext context)
    {
        return _repo.GetSingle<T>(context.SourceValue);
    }
}

IdToEntityConverter在其构造函数中接受一个IRepository ,以通过点击数据库将ID转换回实际的实体。 注意它没有默认的构造函数。

在我的ASP.NET的Global.asax ,这是我对OnApplicationStarted()CreateKernel()

protected override void OnApplicationStarted()
{
    // stuff that's required by MVC
    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes);

    // our setup stuff
    AutoMapperConfiguration.SetupMappings();
}

protected override IKernel CreateKernel()
{
    var kernel = new StandardKernel();
    kernel.Bind<IRepository>().To<NHibRepository>();

    return kernel;
}

所以OnApplicationCreated()会调用AutoMapperConfiguration.SetupMappings()来设置映射,而CreateKernel()会将NHibRepository一个实例绑定到IRepository接口。

问题

每当我运行此代码并尝试让AutoMapper将类别标识转换回类别实体时,我会得到一个AutoMapperMappingException ,它表示IdToEntityConverter上不存在默认构造IdToEntityConverter

尝试

  • IdToEntityConverter添加了一个默认构造IdToEntityConverter 。 现在我得到一个NullReferenceException ,它向我表明注入不起作用。

  • 将私人_repo字段设置为公共属性并添加[Inject]属性。 仍然得到NullReferenceException

  • 在采用IRepository的构造函数中添加了[Inject]属性。 仍然得到NullReferenceException

  • 考虑到Ninject可能无法拦截OnApplicationStarted()AutoMapperConfiguration.SetupMappings()调用,我将它移动到我知道正在注入的东西,我的控制器之一,如下所示:

    public class RepositoryController : Controller
    {
        static RepositoryController()
        {
            AutoMapperConfiguration.SetupMappings();
        }
    }
    

    仍然得到NullReferenceException

  • 我的问题是,我如何让Ninject将IRepository注入到IdToEntityConverter


    你必须让AutoMapper访问DI容器。 我们使用StructureMap,但我想下面应该适用于任何DI。

    我们使用这个(在我们的一个Bootstrapper任务中)...

        private IContainer _container; //Structuremap container
    
        Mapper.Initialize(map =>
        {
            map.ConstructServicesUsing(_container.GetInstance);
            map.AddProfile<MyMapperProfile>();
        }
    

    @ ozczecho的答案是现货,但我发布了Ninject版本的代码,因为它有一点让我们想起了一段时间:

    IKernel kernel = null; // Make sure your kernel is initialized here
    
    Mapper.Initialize(map =>
    {
        map.ConstructServicesUsing(t => kernel.Get(t));
    });
    

    你不能只传入kernel.Get map.ConstructServicesUsing因为除了Type之外,该方法还有一个params参数。 但是因为params是可选的,所以你可以创建lambda表达式来生成一个匿名函数来得到你所需要的。

    链接地址: http://www.djcxy.com/p/74393.html

    上一篇: How do I use AutoMapper with Ninject.Web.Mvc?

    下一篇: AutoMapper: "Ignore the rest"?