`Autofac 与自托管 Owin 服务器的集成为所有具有依赖项的 WebApi 控制器返回 404

问题描述 投票:0回答:0

概述

我们有一个解决方案,我们正在为 DI 从 ninject 切换到 autofac。

我们有一个控制台应用程序(.net 4.8)启动两个单独的进程在本地进行测试。它启动一个 owin 网络应用程序和一个规则引擎。每个进程配置自己的 Autofac 容器(就像它对 ninject 所做的那样)。引擎启动良好,并使用 autofac 启动所有独立的定期线程和后台服务。我们还有单独的端到端测试,使用 autofac 容器进行其他测试。注册在这些测试中正常工作。

Owin 应用程序启动并在开发项目中有一些模拟控制器,并从生产 WebApi 程序集中注册控制器。

详细信息和故障排除

我关注了 autofac owin 集成快速入门,并阅读并尝试了其他类似帖子中关于 autofac 和 WebApi 的 404 错误的解决方案。最初,我认为从单独的程序集注册控制器时出现问题,但我确认控制器确实已在 autofac 容器中注册,并确保在调用

RegisterApiControllers()
后已注册,以确保它没有被注册为POCO 对象而不是 ApiController。

当我完全删除 autofac 容器时,我得到了相同的行为,所以我认为 Owin 根本没有使用 autofac 在需要时提供控制器。

我还尝试在 MockupUserscontroller 的同一个程序集中创建一个全新的控制器,如果我没有任何依赖项,它就可以工作。添加依赖项后,我立即收到 404 错误。似乎 Owin 忽略了任何没有默认构造函数的控制器,但我无法让它工作。

同样,所有这些测试都以 ninject 作为容器正常工作。更换 DI 容器时,控制器没有任何变化。

代码

启动自托管 owin 应用程序和引擎的主要顶级服务。


    public static void Start()
    {
        var baseAddress = "http://localhost:8888";
        app = WebApp.Start<Startup>(baseAddress);
    }

欧文创业班:

public void Configuration(IAppBuilder app)
{
    var config = new HttpConfiguration();
    config.MapHttpAttributeRoutes();
    // Top level error handling. Catches web api layer errors, etc.
    app.Use(
        async (ctx, next) =>
        {
            try
            {
                await next();
            }
            catch (Exception ex)
            {
                this.logger.Error(ex);
#if DEBUG
                throw;
#endif
            }
        });
    var dependencyInjectionServiceFactory = new DependencyInjectionServiceFactory();
    var dependencyInjectionService = dependencyInjectionServiceFactory.CreateWebDevelopmentDependencyInjectionService();
    var containerBuilder = dependencyInjectionService.RegisterServices();
    containerBuilder.RegisterWebApiFilterProvider(config);
    containerBuilder.RegisterType<MockAuthenticationFilter>().AsSelf().SingleInstance();
    var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(t => t.FullName.Contains("Sepsis") && !t.FullName.Contains("DependencyInjection")).ToList();
    containerBuilder.RegisterApiControllers(assemblies.ToArray()).InstancePerRequest();
    var container = containerBuilder.Build();

    logger.Info(string.Join(",\n", assemblies.Select(a => a.FullName)));
    logger.Info($"\nIs {nameof(ProvidersController)} registered? " + container.IsRegistered<ProvidersController>());

    config.Filters.Add(container.Resolve<MockAuthenticationFilter>());
    var webApiResolver = new AutofacWebApiDependencyResolver(container);
    config.DependencyResolver = webApiResolver;
    app.UseAutofacMiddleware(container)
        .UseAutofacWebApi(config)
        .UseWebApi(config)
        .Use<RedirectMiddleware>()
        .UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    
    ConfigureTestData();
    logger.Info("Hey, I'm done and have not crashed.");
}

模型控制器正常工作(不需要 DI)并且与启动引擎和 Owin 的主要服务位于同一程序集中

public class MockupUsersController : ApiController
{
    private readonly MockupUserRepository mockupUserRepository = new MockupUserRepository();

    [HttpGet]
    [Route("mockup_users/{org}")]
    public IEnumerable<User> Get(int org)
    {
        return mockupUserRepository.FindOrganization(org);
    }
}

驻留在生产 webapi 程序集中的控制器 [并非所有方法都被复制],但没有一个端点工作 - 全部返回 404 错误

public class ProvidersController : BaseControllerWithSessionContext
{
    private readonly IPatientService patientService;
    private readonly IRulesService rulesService;
    private readonly IProvidersService providersService;
    private readonly IContactService contactService;
    private readonly IKpiLoggingService kpiLoggingService;
    private readonly IPhiViewLogger phiViewLogger;
    private readonly IProviderImportService providerImportService;

    public ProvidersController(
        IPatientService patientService,
        IRulesService rulesService,
        IProvidersService providersService,
        IContactService contactService,
        IKpiLoggingService kpiLoggingService,
        IPhiViewLogger phiViewLogger,
        IServiceResultHandler serviceResultHandler,
        ISessionContextService sessionContextService,
        IProviderImportService providerImportService)
        : base(serviceResultHandler, sessionContextService)
    {
        this.rulesService = rulesService;
        this.patientService = patientService;
        this.providersService = providersService;
        this.contactService = contactService;
        this.kpiLoggingService = kpiLoggingService;
        this.phiViewLogger = phiViewLogger;
        this.providerImportService = providerImportService;
    }

    /// <summary>
    /// Get all providers for organization
    /// </summary>
    [HttpGet]
    [Route("sites/{SiteId}/providers")]
    [AuthorizeRoles(Roles.Administrator, Roles.User)]
    public IEnumerable<FrontendProvider> GetAll([FromUri] SiteRequest request)
    {
        return providersService.All(request.SiteId);
    }
}

任何帮助表示赞赏。我的想法已经用完了。

asp.net-web-api2 owin autofac self-hosting
© www.soinside.com 2019 - 2024. All rights reserved.