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

时间:2018-03-22 06:40:24

标签: c# api web runtime autofac

我有一个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
     }
    }
    
  3. 问题:

    Autofac通常如何在Web API中运行?首先,我使用的是全局静态IContainer。其次,如果我公开更多的函数,代码看起来是重复的。

    我正在考虑解决API构造函数中的ServiceItem。但授权令牌尚不可用。

    任何建议都表示赞赏。

    P.S:

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

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

1 个答案:

答案 0 :(得分:2)

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

为准

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

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

    ....
}