【问题标题】:How do I use AutoMapper with Ninject.Web.Mvc?如何将 AutoMapper 与 Ninject.Web.Mvc 一起使用?
【发布时间】:2010-11-02 02:54:32
【问题描述】:

设置

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

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

其中IdToEntityConverter&lt;T&gt; 是自定义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 将类别 ID 转换回类别实体时,我都会收到一个 AutoMapperMappingException,它表示 IdToEntityConverter 上不存在默认构造函数。

尝试

  1. IdToEntityConverter 添加了默认构造函数。现在我收到了一个NullReferenceException,它向我表明注入不起作用。

  2. 将私有_repo 字段设为公共属性并添加[Inject] 属性。仍然收到NullReferenceException

  3. 在采用IRepository 的构造函数上添加了[Inject] 属性。仍然收到NullReferenceException

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

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

    仍然收到NullReferenceException

问题

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

【问题讨论】:

    标签: c# dependency-injection inversion-of-control ninject automapper


    【解决方案1】:

    @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,因为该方法除了类型之外还有一个params 参数。但由于参数是可选的,您只需创建 lambda 表达式即可生成一个匿名函数来获得您所需要的。

    【讨论】:

    • 如何初始化kernel
    【解决方案2】:

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

    我们使用它(在我们的引导程序任务之一中)...

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

    【讨论】:

      猜你喜欢
      • 2019-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-12
      • 1970-01-01
      • 2019-10-07
      • 1970-01-01
      相关资源
      最近更新 更多