如何为自托管 MVC 4 API 控制器配置依赖注入

How to configure dependency injection for self hosted MVC 4 API controllers

检查了所有关于 SO 的类似问题后,我的问题仍然存在,所以我为其提出了一个新问题。

我有一个引用另一个项目的单元测试,该项目包含一个 MVC 4 ApiController,它有一个用于依赖注入的构造函数。

public class DataController : ApiController
{
    public DataController(IRepository repository){}    
}

在我的测试中,我使用 Microsoft.Extensions.DependencyInjection 并进行了以下设置:

// Note: this redundant type access is necessary to load controllers from a different assembly,
// see 
var type = typeof(DataController);

var services = new ServiceCollection().AddSingleton<IRepository>(new ImMemoryRepository());
var httpConfiguration = new HttpConfiguration
{ 
    DependencyResolver = new DependencyResolver(services.BuildServiceProvider()),
    IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always
};
httpConfiguration.Routes.MapHttpRoute("Default", "{controller}/{action}");
httpConfiguration.DependencyResolver = new DependencyResolver(services.BuildServiceProvider());
var httpServer = new HttpServer(httpConfiguration);
var client = new HttpClient(httpServer);
var response = await client.GetAsync("http://whatever/data/getdata?id=000");

并且我在测试 class:

中有一个相当简单的依赖解析器实现作为嵌套私有 class
private class DependencyResolver : IDependencyResolver
{
    private readonly ServiceProvider _serviceProvider;

    public DependencyResolver(ServiceProvider serviceProvider) => _serviceProvider = serviceProvider;

    public void Dispose() => _serviceProvider.Dispose();

    public object GetService(Type serviceType) => _serviceProvider.GetService(serviceType);

    public IEnumerable<object> GetServices(Type serviceType) => _serviceProvider.GetServices(serviceType);

    public IDependencyScope BeginScope() => new Scope(_serviceProvider.CreateScope());

    private class Scope : IDependencyScope
    {
        private readonly IServiceScope _scope;

        public Scope(IServiceScope scope) => _scope = scope;

        public void Dispose() => _scope.Dispose();

        public object GetService(Type serviceType) => _scope.ServiceProvider.GetService(serviceType);

        public IEnumerable<object> GetServices(Type serviceType) => _scope.ServiceProvider.GetServices(serviceType);
    }
}

我从测试中得到的响应是 500 服务器错误说

Type 'Mvc.DataController' does not have a default constructor

似乎我正在做所有其他人在 MVC 4 中为依赖注入所做的事情,即使是 this question that has a very similar symptom

我是不是漏掉了什么明显的东西?

更新

我试过 NinjectResolver 归结为同样的问题:

var kernel = new StandardKernel();
kernel.Bind<IRepository>().ToConstant(new InMemoryRepository());
var httpConfiguration = new HttpConfiguration
{
    DependencyResolver = new NinjectResolver(kernel)
};

我想通了。

关键是你还需要在你的依赖配置中添加你正在点击的控制器。

就我而言,我只需要添加:

var services = new ServiceCollection();

// This is what was missing.
services.AddTransient<DataController>();

摘自此处(虽然我根本没有使用 OWIN):How to add Microsoft.Extensions.DependencyInjection to OWIN Self-Hosted WebApi

另一个使用 Autofac 的例子:

var builder = new ContainerBuilder();

// You need to register the assembly that contains your controller.
builder.RegisterApiControllers(typeof(DataController).Assembly);

取自此处:Dependency injection not working with Owin self-hosted Web Api 2 and Autofac