【问题标题】:How to use AutoFac in Web API to resolve a service at runtime?如何在 Web API 中使用 AutoFac 在运行时解析服务?
【发布时间】:2018-08-31 12:07:20
【问题描述】:

我有一个 API (eg: ItemController.cs),它将在运行时从请求标头中获取授权令牌。使用令牌,然后只有我进入我的服务类 (eg: 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。但授权令牌尚不可用。

欢迎提出任何建议。

附注:

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

     public class ServiceItem
     {
          public string token;
          public ServiceItem(string token)
          {
              this.token = token;
          }

          public void doSomething()
          {
              //based on token, do processing
          }
      }

【问题讨论】:

  • 您需要将DependencyResolver设置为AutoFac容器。
  • @john 感谢您指出依赖解析器。我还在Autofac Doc 中找到了它。顺便问一下,运行时如何解决?
  • 你可以把你需要的服务放在控制器构造函数中。
  • 现在我理解并测试了。通过使用 DependencyResolver,它避免了在我的示例中使用“静态”变量。但是,不确定我是否弄错了什么。这只有在我的 ServiceItem 没有参数时才有效。如果我想使用运行时信息(例如来自请求标头的令牌)来解析服务,它是如何执行的?
  • 你可以创建delegate factories并注入它们。

标签: c# api web runtime autofac


【解决方案1】:

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

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

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; 
    }

    ....
}

【讨论】:

  • 是的 +1。感谢您的示例代码。我现在明白使用静态变量是个坏主意。在这里,我会按照您提到的那样做:将其注入 WebAPI 的构造函数中。现在我要弄清楚约翰建议的“委托工厂”是如何工作的
  • 如果有人感兴趣,请添加更多信息。在Best Practice..中提到了它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-22
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-27
相关资源
最近更新 更多