【问题标题】:asp.net adding ApiController as service for dependency injectionasp.net 添加 ApiController 作为依赖注入服务
【发布时间】:2019-01-12 10:39:44
【问题描述】:

您好,我离开 this guide 将 asp.net 核心依赖注入集成到 MVC 5 中。最初使用默认控制器(继承自 System.Web.Mvc.Controller 类)可以正常工作。但后来我希望注入的依赖项在从System.Web.Http.ApiController 继承的控制器中可用。我 95% 确定问题出在代码的这一部分,其中所有控制器都作为服务添加,因为我遇到的错误与指南所说的相同,如果没有这部分,我会得到。

一个缺少方法异常,说明你的构造函数没有实现默认的无参数构造函数

Startup.cs

public static class ServiceProviderExtensions
{
   public static IServiceCollection AddControllersAsServices(this IServiceCollection services,
      IEnumerable<Type> controllerTypes)
   {
      foreach (var type in controllerTypes)
      {
         services.AddTransient(type);
      }

      return services;
   }
}

public partial class Startup
{
  public void ConfigureServices(IServiceCollection services){
    PackageScraperService pScraper = new PackageScraperService();
    services.addSington<IPackageScraper>(pScraper);

    // Problem Code

    services.AddControllersAsServices(typeof(Startup).Assembly.GetExportedTypes()
     .Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition)
     .Where(t => typeof(IController).IsAssignableFrom(t) 
        || t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)));
  }

  public void Configuration(IAppBuilder app){
      var services = new ServiceCollection();

      ConfigureServices(services)
      var resolver = new DefaultDependencyResolver(services.BuildServiceProvider());
      DependencyResolver.SetResolver(resolver);
  }
}

我查看了结果

typeof(Startup).Assembly.GetExportedTypes()
     .Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition)
     .Where(t => typeof(IController).IsAssignableFrom(t) 
        || t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase))

它似乎正确地找到了我的 ApiController (ValuesController.cs)

我还将我的 api 控制器更改为从 Controller 类继承,它工作正常。

有没有更简单的方法将控制器添加为服务?因为我使用的是 MVC 而不是 Core,所以我很难找到这方面的文档。

【问题讨论】:

  • Web api 使用不同的依赖解析器。没有看到你设置那个。链接的指南仅适用于 MVC 控制器
  • 嗯,可以使用 Microsoft 的依赖解析器还是我必须使用 Unity 等进行 web api?
  • 就像你必须为 mvc 创建一个包装解析器一样,你必须为 Web API 做同样的事情。 IDependencyResolver 也存在于 web api 中,但在不同的命名空间中。然后为 GlobalConfiguration 设置解析器

标签: c# asp.net asp.net-mvc asp.net-web-api dependency-injection


【解决方案1】:

更新以包含ApiControllers

services.AddControllersAsServices(typeof(Startup).Assembly.GetExportedTypes()
     .Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition)
     .Where(t => typeof(IController).IsAssignableFrom(t) 
        || typeof(IHttpController).IsAssignableFrom(t));

您还需要为 Web API 全局配置设置依赖解析器。

更新 DefaultDependencyResolver 以便 MVC 和 Web API 都可以使用它。它们按名称共享一个接口,但属于不同的命名空间。

public class DefaultDependencyResolver :
    System.Web.Http.Dependencies.IDependencyResolver,
    System.Web.Mvc.IDependencyResolver {

    private readonly IServiceProvider serviceProvider;

    public DefaultDependencyResolver(IServiceProvider serviceProvider) {
        this.serviceProvider = serviceProvider;
    }    

    public object GetService(Type serviceType) {
        return this.serviceProvider.GetService(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType) {
        return this.serviceProvider.GetServices(serviceType);
    }

    //Web API specific

    public System.Web.Http.Dependencies.IDependencyScope BeginScope() {
        return this;
    }

    public void Dispose() {
        // NO-OP, as the container is shared. 
    }
}

并在启动时为 MVC 和 Web API 设置解析器。

public void Configuration(IAppBuilder app){
    var services = new ServiceCollection();    
    ConfigureServices(services);        
    var resolver = new DefaultDependencyResolver(services.BuildServiceProvider());
    DependencyResolver.SetResolver(resolver);//Set MVC
    GlobalConfiguration.Configuration.DependencyResolver = resolver; //Set for Web API
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-24
    • 2017-01-23
    • 2014-02-25
    • 1970-01-01
    • 1970-01-01
    • 2020-09-15
    • 2020-09-09
    • 1970-01-01
    相关资源
    最近更新 更多