使用AutoMapper时激活IConfigurationProvider时出错

时间:2017-10-09 10:16:35

标签: c# entity-framework asp.net-mvc-5 automapper ninject

我正在使用Entity Framework 6开发.NET MVC 5应用程序。 我已经创建了我的数据库。然后我创建了一个简单的ViewModel并在HomeController中使用它。但是当我尝试将ViewModel映射到控制器中的Database模型时,我得到了这个错误:

  

激活IConfigurationProvider时出错   没有匹配的绑定可用,并且该类型不可自绑定。   激活路径:    3)将依赖关系IConfigurationProvider注入参数configurationProvider,类型为Mapper的构造函数    2)将依赖IMapper注入到HomeController类型构造函数的参数映射器中    1)请求HomeController

     

建议:1)确保您已为其定义了绑定   IConfigurationProvider。 2)如果绑定是在模块中定义的,   确保模块已加载到内核中。 3)确保你   没有意外创建多个内核。 4)如果你是   使用构造函数参数,确保参数名称匹配   构造函数参数名称。 5)如果您使用的是自动模块   加载,确保搜索路径和过滤器正确无误。

这是我的HomeController:

public ActionResult Index()
    {
        var ads = this.adService
            .GetAll()
            .ToList()
            .Select(x => this.mapper.Map<AdViewModel>(x));


        var viewModel = new MainViewModel()
        {
            Ads = ads,
        };

        return View(viewModel);

        //return View();
    }

这是我的AutoMapperConfiguration:

public class AutoMapperConfig
{
    public static IMapperConfigurationExpression Configuration { get; private set; }

    public void Execute(Assembly assembly)
    {
        Mapper.Initialize(
            cfg =>
            {
                var types = assembly.GetExportedTypes();
                LoadStandardMappings(types, cfg);
                LoadCustomMappings(types, cfg);
                Configuration = cfg;
            });
    }

    private static void LoadStandardMappings(IEnumerable<Type> types, IMapperConfigurationExpression mapperConfiguration)
    {
        var maps = (from t in types
                    from i in t.GetInterfaces()
                    where i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>) &&
                          !t.IsAbstract &&
                          !t.IsInterface
                    select new
                    {
                        Source = i.GetGenericArguments()[0],
                        Destination = t
                    }).ToArray();

        foreach (var map in maps)
        {
            mapperConfiguration.CreateMap(map.Source, map.Destination);
            mapperConfiguration.CreateMap(map.Destination, map.Source);
        }
    }

    private static void LoadCustomMappings(IEnumerable<Type> types, IMapperConfigurationExpression mapperConfiguration)
    {
        var maps = (from t in types
                    from i in t.GetInterfaces()
                    where typeof(IHaveCustomMappings).IsAssignableFrom(t) &&
                          !t.IsAbstract &&
                          !t.IsInterface
                    select (IHaveCustomMappings)Activator.CreateInstance(t)).ToArray();

        foreach (var map in maps)
        {
            map.CreateMappings(mapperConfiguration);
        }
    }
}

}

NinjectConfig:

 private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind(x =>
        {
            x.FromThisAssembly()
             .SelectAllClasses()
             .BindDefaultInterface();
        });

        kernel.Bind(x =>
        {
            x.FromAssemblyContaining(typeof(IService))
             .SelectAllClasses()
             .BindDefaultInterface();
        });

        kernel.Bind(typeof(IEfRepository<>)).To(typeof(EfRepository<>));
        kernel.Bind(typeof(DbContext), typeof(MsSqlDbContext)).To<MsSqlDbContext>().InRequestScope();
        kernel.Bind<ISaveContext>().To<SaveContext>();
        kernel.Bind<IMapper>().To<Mapper>();

    }

Global.asax:

 protected void Application_Start()
    {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<MsSqlDbContext, Configuration>());

        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        var mapper = new AutoMapperConfig();
        mapper.Execute(Assembly.GetExecutingAssembly());
    }

我期待看到解决此错误的想法,以及如何注入此IConfigurationProvider?

1 个答案:

答案 0 :(得分:0)

我没有尝试解析IConfigurationProvider依赖关系,而是建议将IMapper映射到已经初始化的Mapper实例的方法。 现在,自动化器初始化代码将在Ninject配置时执行,而不是在Global.asax中执行。

我建议的更改如下:

AutoMapperConfig.cs:

public static class AutoMapperConfig
{
    public static IMapperConfigurationExpression Configuration { get; private set; }
    public static IMapper MapperInstance { get; private set; }

    static AutoMapperConfig()
    {
        Mapper.Initialize(cfg =>
        {
            var types = Assembly.GetExecutingAssembly().GetExportedTypes();
            LoadStandardMappings(types, cfg);
            LoadCustomMappings(types, cfg);
            Configuration = cfg;
        });

        MapperInstance = Mapper.Instance;
    }

    private static void LoadStandardMappings(IEnumerable<Type> types, IMapperConfigurationExpression mapperConfiguration)
    {
        var maps = (from t in types
                    from i in t.GetInterfaces()
                    where i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>) &&
                          !t.IsAbstract &&
                          !t.IsInterface
                    select new
                    {
                        Source = i.GetGenericArguments()[0],
                        Destination = t
                    }).ToArray();

        foreach (var map in maps)
        {
            mapperConfiguration.CreateMap(map.Source, map.Destination);
            mapperConfiguration.CreateMap(map.Destination, map.Source);
        }
    }

    private static void LoadCustomMappings(IEnumerable<Type> types, IMapperConfigurationExpression mapperConfiguration)
    {
        var maps = (from t in types
                    from i in t.GetInterfaces()
                    where typeof(IHaveCustomMappings).IsAssignableFrom(t) &&
                          !t.IsAbstract &&
                          !t.IsInterface
                    select (IHaveCustomMappings)Activator.CreateInstance(t)).ToArray();

        foreach (var map in maps)
        {
            map.CreateMappings(mapperConfiguration);
        }
    }
}

NinjectConfig:

private static void RegisterServices(IKernel kernel)
{
    kernel.Bind(x =>
    {
        x.FromThisAssembly()
         .SelectAllClasses()
         .BindDefaultInterface();
    });

    kernel.Bind(x =>
    {
        x.FromAssemblyContaining(typeof(IService))
         .SelectAllClasses()
         .BindDefaultInterface();
    });

    kernel.Bind(typeof(IEfRepository<>)).To(typeof(EfRepository<>));
    kernel.Bind(typeof(DbContext), typeof(MsSqlDbContext)).To<MsSqlDbContext>().InRequestScope();
    kernel.Bind<ISaveContext>().To<SaveContext>();
    kernel.Bind<IMapper>().ToMethod(ctx => AutoMapperConfig.MapperInstance);
}

的Global.asax:

protected void Application_Start()
{
    Database.SetInitializer(new MigrateDatabaseToLatestVersion<MsSqlDbContext, Configuration>());

    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
 }