Skip to main content
 首页 » 编程设计

c#之如何在 Web API 中使用 AutoFac 在运行时解析服务

2024年02月25日29lovecherry

我有一个 API(例如:ItemController.cs)可以在运行时从请求 header 获取授权 token 。使用 token ,然后只有我传递到我的服务类(例如:ServiceItem.cs)。

这是我的做法。

  1. 在 Startup.cs 中,我注册了我的 ServiceItem

    var builder = new ContainerBuilder(); 
    builder.RegisterType<ServiceItem>(); 
    container = builder.Build(); //Note that, my container is a static variable 
    
  2. 在我的 API 中,我是这样解决的:

    [Authorize] 
    [Route("GetData")] 
    [HttpGet] 
    public IHttpActionResult GetData([FromUri] Filter filter) 
    { 
     using (var scope = Startup.container.BeginLifetimeScope()) 
     { 
        var serviceItem = Startup.container.Resolve<ServiceItem>( 
                new NamedParameter("token", Request.GetHeader("Authorization")) 
            ); 
        return Ok(serviceItem.getItem(filter)); //filter is a param from webAPI 
     } 
    } 
    

问题:

这是 Autofac 通常在 Web API 中的工作方式吗?首先,我使用的是全局静态 IContainer。其次,如果我再公开几个函数,代码看起来会重复。

我想在 API 的构造函数中解析 ServiceItem。但授权 token 尚不可用。

如有任何建议,我们将不胜感激。

附言:

这是我的 ServiceItem,它在构造函数中有一个参数“token”

     public class ServiceItem 
     { 
          public string token; 
          public ServiceItem(string token) 
          { 
              this.token = token; 
          } 
 
          public void doSomething() 
          { 
              //based on token, do processing 
          } 
      } 

请您参考如下方法:

在启动类中引用静态容器是个坏主意。这样,您就可以在 Controller 和启动之间引入紧密耦合。您的 Controller 依赖项应由构造函数参数满足。取自 http://docs.autofac.org/en/v4.0.0/integration/aspnetcore.html

Startup.ConfigureServices 方法可以选择返回一个 IServiceProvider 实例,它允许您将 Autofac 插入到 ASP.NET Core 依赖注入(inject)框架中:

public IServiceProvider ConfigureServices(IServiceCollection services) 
{ 
  services.AddMvc(); 
 
  var builder = new ContainerBuilder(); 
 
  builder.RegisterType<MyType>().As<IMyType>(); 
  builder.Populate(services); 
  this.ApplicationContainer = builder.Build(); 
 
  return new AutofacServiceProvider(this.ApplicationContainer); 
} 

初始化容器后,构造函数参数将由 Autofac 自动解析:

public class MyController 
{ 
    private readonly IMyType theType; 
    public MyController(IMyType theType) 
    { 
        this.theType = theType;  
    } 
 
    .... 
}