Autofac RegisterGeneric 适用于单元测试但不适用于应用程序

Autofac RegisterGeneric works in unit test but not in application

我有一个 ASP.NET MVC 6 (Framework 4.6.1) 应用程序,Autofac 版本为 4.0.0-rc1-177。

在我的 Startup.cs 中,我调用了我制作的 AutofacLoader:

var container = Core.DI.AutofacLoader.Configure(services).Build();

AutofacLoader class:

public class AutofacLoader
{
    public static IContainer Container { get; set; }

    /// <summary>
    /// Register the DI modules through AutoFac
    /// </summary>
    /// <param name="services">IServiceCollection to register the modules on</param>
    /// <returns></returns>
    public static ContainerBuilder Configure(IServiceCollection services)
    {
        var builder = new ContainerBuilder();

        builder.RegisterModule<LogRequestsModule>();
        //Core
        builder.RegisterModule(new Core.ServiceModules.AutoMapperModule());
        builder.RegisterModule(new Core.ServiceModules.ServicesModule());
        builder.RegisterModule(new DAL.ServicesModules.IBSRepositoriesModule());

        //Dieet
        builder.RegisterModule(new Dieet.Core.ServiceModules.AutoMapperModule());
        builder.RegisterModule(new Dieet.Core.ServiceModules.ServicesModule());
        builder.RegisterModule(new Dieet.DAL.ServicesModules.DieetRepositoriesModule());

        //builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());
        if (services == null)
        {
            Container = builder.Build();
        }
        else
        {
            builder.Populate(services);

        }
        return builder;
    }
}

我的 IBS.Core.ServicesModules.ServiceModule class(当我在此 class 中放置一个断点时,在启动我的应用程序时被调用,所以由 AutofacLoader class):

namespace IBS.Core.ServiceModules
{
    public class ServicesModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            var assembly = System.Reflection.Assembly.GetExecutingAssembly();
            builder.RegisterAssemblyTypes(assembly)
                .Where(t => t.Name.EndsWith("Service"))
                .AsImplementedInterfaces();
            builder.RegisterGeneric(typeof(PaginatedSearchViewModel<>)).As(typeof(IPaginatedSearchViewModel<>)).InstancePerLifetimeScope();
        }
    }
}

我的 xunit 测试(使用 FluentAssertions)通过了:

public class ServiceModulesTest
{
    [Fact]
    public void ShouldBeInstantiatable()
    {
        AutofacLoader.Configure(null);
        var container = AutofacLoader.Container;
        var instance = container.Resolve<IPaginatedSearchViewModel<PatientViewModel>>();

        instance.Should().BeOfType<PaginatedSearchViewModel<PatientViewModel>>();
    }
}

但是当我 运行 应用程序时,在我的一个 API 控制器中,我有例如这个方法:

    [HttpGet("patienten")]
    public async Task<PagedResult<PatientViewModel>> GetPatientsAsync(IPaginatedSearchViewModel<PatientFilters> vm)
    {
        return await _infohosService.GetAllPatientsWithDossiersAndVerpleegperiodesAsync(vm);
    }

这在浏览器中失败并响应:无法解析接口。

当我自己将 IPaginatedSearchViewModel 更改为参数中的具体 class 时:

    [HttpGet("patienten")]
    public async Task<PagedResult<PatientViewModel>> GetPatientsAsync(PaginatedSearchViewModel<PatientFilters> vm)
    {
        return await _infohosService.GetAllPatientsWithDossiersAndVerpleegperiodesAsync(vm);
    }

API 有效。

所以我的问题是:

  1. 为什么我的单元测试通过了? (我是单元测试的新手,所以也许我在这里做错了什么?)

  2. 我怎样才能让 Autofac 也解析这个接口,因为它适用于我所有的服务、存储库、IDbContext,...?

I'm not sure if asp.net mvc 6 uses DI container on model binding stage

确实是这个问题。我已经 Google 多了一些,但没有发现 MVC 6 在模型绑定阶段使用 DI 容器。

使用方法中的具体class解决