dependency-injection - 为什么 ServiceProvider 无法在 ASP.NET Core 中创建 Controller 实例?

标签 dependency-injection asp.net-core asp.net-core-mvc

我在 .NET Core 中开发集成测试。因为 Controller 有多个依赖项,所以手动创建它们的实例很不方便。以下是我如何创建 ServiceProvider 实例以能够访问 .NET Core native DI 容器:

HostingEnvironment env = new HostingEnvironment();
env.ContentRootPath = Directory.GetCurrentDirectory();
env.EnvironmentName = "Development";

Startup startup = new Startup(env);
ServiceCollection sc = new ServiceCollection();
startup.ConfigureServices(sc);
ServiceProvider = sc.BuildServiceProvider();

Startup 类取自测试程序集。

令我惊讶的是,服务提供商无法创建 Controller 实例。它可以实例化已注册的服务,但不能实例化 Controller 。有人知道为什么会这样吗?

最佳答案

您应该使用 TestServer,它会引导一个完整的测试环境(可选择使用不同的启动类或环境变量,您可以在其中将数据存储替换为内存存储)。

ASP.NET 核心 documentation很好地涵盖了这个案例。

var server = new TestServer(new WebHostBuilder()
    .UseStartup<Startup>()
    // this would cause it to use StartupIntegrationTest or ConfigureServicesIntegrationTest / ConfigureIntegrationTest methods (if existing)
    // rather than Startup, ConfigureServices and Configure
    .UseEnvironment("IntegrationTest"));

在这些替代/环境相关的方法中,您可以将集成测试特定的替换/DI 配置。

其次,默认情况下, Controller (以及标签助手和 View 组件)未注册到 DI 系统。 Controller 工厂将解析类型。如果您希望通过内置或第三方 IoC 容器解析 Controller ,则必须告诉 ASP.NET Core 显式注册它们(请参阅 this related question)。

这是一个例子:

services
    .AddMvc()
    .AddControllersAsServices()
    .AddViewComponentsAsServices()
    .AddTagHelpersAsServices();

我建议您使用第一种方法,因为它更一致,并且正是存在具有环境支持的 Startup 类的原因。

更新

重要补充。如果您使用 TestServer,您还可以访问其 DI 容器(IServiceProvider 实例)。

var server = new TestServer(new WebHostBuilder()
        .UseStartup<Startup>()
        .UseEnvironment("IntegrationTest"));
var controller = server.Host.Services.GetService<MyController>();

关于dependency-injection - 为什么 ServiceProvider 无法在 ASP.NET Core 中创建 Controller 实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42222919/

相关文章:

logging - 如何配置 ILogger 以将日志输出到特定文件?

jquery - MVC 6 - 无法再将多个 JSON 参数传递给 Controller

c# - 在 httpcontext asp.net core 上缓存对象

asp.net-mvc - ASP.NET MVC 的自定义 Controller 工厂、依赖注入(inject)/结构图问题

macos - 将 ManagedObjectContext 获取到初始 viewController OS X 的方法

javascript - 更新 angular-devkit 并失败 : Microsoft. AspNetCore.SpaServices[0]

c# - ASP.NET Core 3.0 [FromBody] 字符串内容返回 "The JSON value could not be converted to System.String."

unit-testing - Pester Mock 不适用于使用脚本 block 的 Invoke-Command

.net - 使用第三方依赖注入(inject)容器比使用我构建的容器有什么好处?

dependency-injection - 如何使用 .NET Core 解析类库中的 DI 类?