You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法同时将Autofac集成至Web API 2与MVC环境

Web API Autofac集成失败排查与解决方案

我已经花了一周时间尝试多种方法解决Autofac集成问题,目前MVC部分已经成功集成Autofac,但Web API始终无法完成集成。以下是我的相关实现代码:


AutofacDi 实现

public static class AutofacDi 
{ 
    public static ValueTuple<IContainer, HttpConfiguration> Initialize() 
    { 
        var assembly = Assembly.GetExecutingAssembly(); 
        var builder = new ContainerBuilder(); 
        var config = GlobalConfiguration.Configuration; 

        builder.RegisterControllers(assembly); 
        builder.RegisterApiControllers(assembly).PropertiesAutowired(); 
        builder.RegisterHttpRequestMessage(config); 
        builder.RegisterAssemblyModules(assembly); 
        builder.RegisterAssemblyTypes(assembly).PropertiesAutowired(); 
        builder.RegisterFilterProvider(); 
        builder.RegisterWebApiFilterProvider(config); 
        builder.RegisterModelBinders(assembly); 
        builder.RegisterWebApiModelBinderProvider(); 
        builder.RegisterModelBinderProvider(); 
        builder.RegisterModule<AutofacWebTypesModule>(); 
        builder.RegisterSource(new ViewRegistrationSource()); 
        builder.RegisterType<T4MVC.Dummy>().AsSelf(); 

        builder.RegisterType<FoodDbContext>() 
            .As<IUnitOfWork>() 
            .InstancePerLifetimeScope(); 
        builder.Register(context => (FoodDbContext)context.Resolve<IUnitOfWork>()) 
            .As<FoodDbContext>() 
            .InstancePerLifetimeScope(); 
        builder.RegisterType<ApplicationDbContext>().As<DbContext>().InstancePerLifetimeScope(); 

        builder.RegisterType<UserStore<ApplicationUser>>().As<IUserStore<ApplicationUser>>(); 
        builder.RegisterType<ApplicationUserManager>(); 
        builder.RegisterType<ApplicationSignInManager>(); 
        builder.Register(c => new IdentityFactoryOptions<ApplicationUserManager>() { DataProtectionProvider = new DpapiDataProtectionProvider("FoodBaMa") }); 
        builder.Register(c => HttpContext.Current.GetOwinContext().Authentication).InstancePerLifetimeScope(); 
        builder.RegisterType<RoleStore<IdentityRole>>().As<IRoleStore<IdentityRole, string>>(); 

        builder.RegisterAssemblyTypes(typeof(MvcApplication).Assembly) 
            .Where(t => t.Name.EndsWith("Service")) 
            .AsImplementedInterfaces() 
            .InstancePerLifetimeScope(); 

        var container = builder.Build(); 
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 
        config.DependencyResolver = new AutofacWebApiDependencyResolver(container); 

        return new ValueTuple<IContainer, HttpConfiguration>(container, config); 
    } 
}

OWIN Startup 代码

[assembly: OwinStartup(typeof(FoodBaMa.Startup))] 
namespace FoodBaMa 
{ 
    public partial class Startup 
    { 
        public void Configuration(IAppBuilder app) 
        { 
            var iOc = AutofacDi.Initialize(); 
            app.UseAutofacMiddleware(iOc.Item1); 
            app.UseAutofacMvc(); 
            app.UseWebApi(iOc.Item2); 
            app.UseAutofacWebApi(iOc.Item2); 
            WebApiConfig.Register(iOc.Item2); 
            app.UseCors(CorsOptions.AllowAll); 
            ConfigureAuth(app); 
        } 
    } 
}

Global.asax 代码

public class MvcApplication : HttpApplication 
{ 
    protected void Application_Start() 
    { 
        RouteConfig.RegisterRoutes(RouteTable.Routes); 
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
        BundleConfig.RegisterBundles(BundleTable.Bundles); 
        ViewEngines.Engines.Clear(); 
        ViewEngines.Engines.Add(new RazorViewEngine()); 
        ModelBinders.Binders.Add(typeof(string), new PersianModelBinder()); 
        MvcHandler.DisableMvcResponseHeader = true; 
        DbInterception.Add(new ElmahEfInterceptor()); 
        DbInterception.Add(new YeKeInterceptor()); 
        GlobalConfiguration.Configuration.EnsureInitialized(); 
    } 
}

ApiController 实现

[AutofacControllerConfiguration] 
[WebApiCompress] 
[RoutePrefix("api/v1")] 
public class AppController : ApiController 
{ 
    private readonly IApiV1Service _apiService; 

    public AppController(IApiV1Service apiService ) 
    { 
        _apiService = apiService; 
    } 

    [HttpPost] 
    [Route("app/mainview")] 
    public virtual async Task<IHttpActionResult> MainView([FromBody] Request model) 
    { 
        var Result = new Models.API.V1.App.MainView.Response { Status = CheckTokenEnum.Error }; 
        try 
        { 
            if (ModelState.IsValid) 
                Result = await _apiService.MainView(model).ConfigureAwait(false); 
        } 
        catch (Exception ex) 
        { 
            ErrorLog.GetDefault(null).Log(new Error(ex)); 
        } 
        return Json(Result, R8.Json.Setting); 
    } 
}

WebApiConfig 代码

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
        config.JsonIntegration(); 
        config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 
        config.MessageHandlers.Add(new CachingHandler(new InMemoryCacheStore())); 
        config.MessageHandlers.Add(new PreflightRequestsHandler()); 
        config.Filters.Add(new ElmahHandleErrorApiAttribute()); 
        config.MapHttpAttributeRoutes(); 
        config.Routes.MapHttpRoute( 
            name: "DefaultApi", 
            routeTemplate: "api/{controller}/{id}", 
            defaults: new { id = RouteParameter.Optional } 
        ); 
    } 
}

RouteConfig 代码(片段)

public class RouteConfig 
{ 
    public static void RegisterRoutes(RouteCollec

问题排查与解决方案

从你的代码来看,Web API集成失败大概率是初始化顺序冲突和配置重复导致的,我整理了几个关键修复点:

  1. 调整OWIN Startup中的Web API注册顺序
    你当前先将Web API加入OWIN管道,再配置WebApiConfig,这会导致路由、过滤器等配置无法生效。修改顺序如下:

    public void Configuration(IAppBuilder app)
    {
        var iOc = AutofacDi.Initialize();
        // 先完成Web API配置,再加入管道
        WebApiConfig.Register(iOc.Item2);
        
        app.UseAutofacMiddleware(iOc.Item1);
        app.UseAutofacMvc();
        app.UseAutofacWebApi(iOc.Item2);
        app.UseWebApi(iOc.Item2);
        
        app.UseCors(CorsOptions.AllowAll);
        ConfigureAuth(app);
    }
    
  2. 移除Global.asax中的Web API初始化代码
    Global.asax里的GlobalConfiguration.Configuration.EnsureInitialized()会和OWIN的Web API初始化产生冲突,直接删除这行代码即可:

    protected void Application_Start()
    {
        // ... 其他保留代码 ...
        // 移除这行,让OWIN完全接管Web API初始化
        // GlobalConfiguration.Configuration.EnsureInitialized();
    }
    
  3. 验证服务注册的正确性
    确认IApiV1Service的实现类命名符合*Service的规则(你的代码里用了Where(t => t.Name.EndsWith("Service"))),如果命名不符合,需要手动注册:

    builder.RegisterType<ApiV1Service>().As<IApiV1Service>().InstancePerLifetimeScope();
    

完成这些修改后,建议在ApiController的构造函数中添加断点,测试IApiV1Service是否能被正确注入。如果仍然失败,查看Elmah日志或调试输出的异常信息,这会帮你进一步定位具体的依赖解析问题。

内容的提问来源于stack exchange,提问作者Arash Sh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:03:16