当我尝试将 Autofac 与 AutoMapper 的 IMappingEngine 结合使用时出现异常

Exception when I try to combine Autofac with AutoMapper`s IMappingEngine

这就是我的 DI 和 Automapper 设置:

[RoutePrefix("api/productdetails")]
public class ProductController : ApiController
{
    private readonly IProductRepository _repository;
    private readonly IMappingEngine _mappingEngine;

    public ProductController(IProductRepository repository, IMappingEngine mappingEngine)
    {
        _repository = repository;
        _mappingEngine = mappingEngine;
    }
}

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);

        //WebApiConfig.Register(GlobalConfiguration.Configuration);          
        RouteConfig.RegisterRoutes(RouteTable.Routes);          
    }
}


public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional });

        // Filter
        config.Filters.Add(new ActionExceptionFilter());
        config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());


        // DI
        // Register services
        var builder = new ContainerBuilder();
        builder.RegisterType<ProductRepository>().As<IProductRepository>().InstancePerRequest();
        builder.RegisterType<MappingEngine>().As<IMappingEngine>();

        // AutoMapper
        RegisterAutoMapper(builder);

        // FluentValidation

        // do that finally!
        // This is need that AutoFac works with controller type injection
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
        var container = builder.Build();
        config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
    }

    private static void RegisterAutoMapper(ContainerBuilder builder)
    {
        var profiles =
            AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(GetLoadableTypes)
                .Where(t => t != typeof (Profile) && typeof (Profile).IsAssignableFrom(t));
        foreach (var profile in profiles)
        {
            Mapper.Configuration.AddProfile((Profile) Activator.CreateInstance(profile));
        }

    }

    private static IEnumerable<Type> GetLoadableTypes(Assembly assembly)
    {
        try
        {
            return assembly.GetTypes();
        }
        catch (ReflectionTypeLoadException e)
        {
            return e.Types.Where(t => t != null);
        }
    }
}

那是我去某条路线时遇到的异常:

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'AutoMapper.MappingEngine' can be invoked with the available services and parameters:
Cannot resolve parameter 'AutoMapper.IConfigurationProvider configurationProvider' of constructor 'Void .ctor(AutoMapper.IConfigurationProvider)'.
Cannot resolve parameter 'AutoMapper.IConfigurationProvider configurationProvider' of constructor 'Void .ctor(AutoMapper.IConfigurationProvider, AutoMapper.Internal.IDictionary`2[AutoMapper.Impl.TypePair,AutoMapper.IObjectMapper], System.Func`2[System.Type,System.Object])'.

问题

我的代码有什么问题?

错误来自这一行:

builder.RegisterType<MappingEngine>().As<IMappingEngine>();

这一行告诉 Autofac 在需要 IMappingEngine 时实例化 MappingEngine。如果您查看 MappingEngine 的可用构造函数,您会发现 Autofac 无法使用其中任何一个,因为它无法注入所需的参数。

这里是MappingEngine

的可用构造函数
public MappingEngine(IConfigurationProvider configurationProvider)
public MappingEngine(IConfigurationProvider configurationProvider, 
                     IDictionary<TypePair, IObjectMapper> objectMapperCache, 
                     Func<Type, object> serviceCtor)

解决此问题的方法之一是告诉 Autofac 如何创建您的 MappingEngine 您可以使用委托注册来完成。

builder.Register(c => new MappingEngine(...)).As<IMappingEngine>();

你也可以这样注册一个IConfigurationProviderAutofac就能自动找到好的构造函数

解决此问题的最简单方法是在 Autofac

中注册一个 IConfigurationProvider
builder.Register(c => new ConfigurationStore(new TypeMapFactory(), MapperRegistry.Mappers))
       .As<IConfigurationProvider>()
       .SingleInstance();
builder.RegisterType<MappingEngine>()
       .As<IMappingEngine>();

您还可以在此处找到更多信息:AutoMapper, Autofac, Web API, and Per-Request Dependency Lifetime Scopes