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

Dan*_* T. 12 c# dependency-injection ninject inversion-of-control automapper

建立

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

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

IdToEntityConverterIRepository在其构造函数中接受一个,以便通过命中数据库将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;
}
Run Code Online (Sandbox Code Playgroud)

因此,OnApplicationCreated()将调用AutoMapperConfiguration.SetupMappings()以设置映射CreateKernel()并将绑定NHibRepositoryIRepository接口的实例.

问题

每当我运行此代码并尝试让AutoMapper将类别ID转换回类别实体时,我得到一个AutoMapperMappingException说明没有默认构造函数IdToEntityConverter.

尝试

  1. 添加了默认构造函数IdToEntityConverter.现在我得到一个NullReferenceException,这表明注射不起作用.

  2. 将私有_repo字段变为公共属性并添加[Inject]属性.还在NullReferenceException.

  3. [Inject]在构造函数上添加了一个属性IRepository.还在NullReferenceException.

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

    public class RepositoryController : Controller
    {
        static RepositoryController()
        {
            AutoMapperConfiguration.SetupMappings();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    还在NullReferenceException.

我的问题是,如何获得Ninject注入一IRepositoryIdToEntityConverter

Cha*_*ung 11

@ ozczecho的回答是现实的,但是我发布了Ninject版本的代码,因为它有一个小小的警告,抓住了我们一段时间:

IKernel kernel = null; // Make sure your kernel is initialized here

Mapper.Initialize(map =>
{
    map.ConstructServicesUsing(t => kernel.Get(t));
});
Run Code Online (Sandbox Code Playgroud)

你不能只是传递kernel.Getmap.ConstructServicesUsing因为该方法具有params除类型参数.但是因为params是可选的,所以你可以创建lambda表达式来生成一个匿名函数来获得你需要的东西.


ozc*_*cho 8

您必须授予AutoMapper访问DI容器的权限.我们使用StructureMap,但我想下面的内容应该适用于任何DI.

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

    private IContainer _container; //Structuremap container

    Mapper.Initialize(map =>
    {
        map.ConstructServicesUsing(_container.GetInstance);
        map.AddProfile<MyMapperProfile>();
    }
Run Code Online (Sandbox Code Playgroud)