如何将依赖于IOwinContext的服务注入自定义OAuthAuthorizationServerProvider

时间:2016-12-22 14:50:48

标签: c# asp.net-web-api2 owin autofac

将IOwinContext注入OAuthAuthorizationServerProvider时出现问题。

在我的Startup.cs中,我有一行:

 public static IContainer ConfigureContainer(Type mvcApplication, HttpConfiguration configuration = null)
    {
        var builder = new ContainerBuilder();
        //other stuff
        builder
          .Register(ctx=>HttpContext.Current.GetOwinContext())
          .As<IOwinContext>();
        //other stuff
      app.UseAutofacMiddleware(container);
      app.UseAutofacWebApi(configuration);
      app.UseWebApi(configuration);
}

在我的提供者中,我这样做:

 public class  ApplicationOAuthProvider : OAuthAuthorizationServerProvider{

     public ApplicationOAuthProvider(IComponentContext context)
    {
        _ccontext = context;
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
           var logger = _ccontext.Resolve<EventLoggerService>();
    }

 }

上面一行崩溃是因为我有一个需要IOwinContext的注射剂。错误是:

  

:Autofac.Core.DependencyResolutionException:可以使用可用的服务和参数调用在'Assistant.Framework.Services.CurrentUserService'类型上找到'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'的构造函数:   无法解析构造函数'Void .ctor(Microsoft.Owin.IOwinContext)'的参数'Microsoft.Owin.IOwinContext context'。

1 个答案:

答案 0 :(得分:2)

短版

如果您使用Autofac and Web API integration using OWIN,则无需自行在容器中注册IOwinContext

集成包Autofac.WebApi2.Owin为您完成。所有你需要做的就是注入IOwinContext注入它的任何地方,它将开箱即用,你可以在this repo on GitHub上看到

更长的版本,a.k.a。“这是怎么发生的?”

原因是当使用OWIN integration package for Autofac时,IOwinContext会在每个请求生命周期范围内自动注册。当您在this file中拨打app.UseAutofac(container)时会发生魔力,这里是代码的摘录:

private static IAppBuilder RegisterAutofacLifetimeScopeInjector(this IAppBuilder app, ILifetimeScope container)
{
    app.Use(async (context, next) =>
        {
            using (var lifetimeScope = container.BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag,
            b => b.RegisterInstance(context).As<IOwinContext>()))
            {
                context.Set(Constants.OwinLifetimeScopeKey, lifetimeScope);
                await next();
            }
        });

    app.Properties[InjectorRegisteredKey] = true;
    return app;
}

在OWIN管道中注册了一个匿名中间件,它做了三件事:

  • 为当前HTTP请求创建新的生命周期范围
  • 在新的生命周期范围内注册当前IOwinContext
  • 将当前生命周期范围存储在IOwinContext

所有这些意味着在Web API应用程序中解析服务的生命周期范围已经知道如何注入IOwinService,因此不需要额外的工作。