asp.net-web-api – Autofac,Owin,Webapi并注入AuthorizationSer
在阅读有关使用owin和webapi的autofac的问题和文章后,我遇到了注入服务的解决方案,但它不起作用.这是我的代码:
public class StartUp { public void Configuration(IAppBuilder app) { HttpConfiguration config = new HttpConfiguration(); WebApiConfig.Register(config); var builder = new ContainerBuilder(); // Create the container builder. builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); // Register the Web API controllers. var authcontext = new AuthContext(); builder.RegisterInstance(authcontext).AsSelf().SingleInstance(); //Updated //var simpleauth = new SimpleAuthorizationServerProvider(); //Updated // builder.RegisterInstance(simpleauth).SingleInstance().AsSelf().PropertiesAutowired(); builder.Register(x => new UserStore<IdentityUser>(authcontext)).As<IUserStore<IdentityUser>>(); //updated builder.Register(x => { var p = new SimpleAuthorizationServerProvider(); var userStore = x.Resolve<IUserStore<IdentityUser>>(); p.userManager = new UserManager<IdentityUser>(userStore); return p; }).AsSelf().PropertiesAutowired(); builder.RegisterType<AuthRepository>().As<IAuthRepository>().InstancePerRequest().PropertiesAutowired(); var container = builder.Build(); var resolver = new AutofacWebApiDependencyResolver(container); // Create an assign a dependency resolver for Web API to use. config.DependencyResolver = resolver; app.UseAutofacMiddleware(container); app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); app.UseWebApi(config); ConfigureOAuth(app,resolver); } public void ConfigureOAuth(IAppBuilder app,AutofacWebApiDependencyResolver resolver) { OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions() { AllowInsecureHttp = true,TokenEndpointPath = new PathString("/token"),AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),//updated Provider = new SimpleAuthorizationServerProvider() //resolver.GetService(typeof(SimpleAuthorizationServerProvider)) as SimpleAuthorizationServerProvider }; // Token Generation app.USEOAuthAuthorizationServer(OAuthServerOptions); app.USEOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); } } 但是在SimpleAuthorizationServerProvider类中,当一个类似ValidateClientAuthentication的方法被调用时,所有的服务都是null,这里是代码: public readonly IAuthRepository repository; public readonly UserManager<IdentityUser> userManager; public readonly AuthContext dbContext; public SimpleAuthorizationServerProvider() { } public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { string clientId; string clientSecret; if (context.TryGetFormCredentials(out clientId,out clientSecret)) { try { Client client = await repository.FindClientById(clientId); } } } 你能帮帮我吗? 更新 如果在ConfigureOAuth方法中,我使用以下方法: OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions() { AllowInsecureHttp = true,Provider = resolver.GetService(typeof(SimpleAuthorizationServerProvider)) as SimpleAuthorizationServerProvider }; 我收到错误: An exception of type 'Autofac.Core.DependencyResolutionException' occurred in Autofac.dll but was not handled in user code Additional information: No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime,never from the container itself. 解决方法
当您注册对象的实例而不是类型时,即使您指定的PropertiesAutowired也不会生效,因为Autofac假定您在创建实例时已完成所需的所有工作.如果要连接属性,则需要在OnActivated处理程序中执行此操作.
在这个示例代码中实际上有很多东西在起作用. > SimpleAuthorizationServerProvider中的值是字段而不是属性,因此PropertiesAutowired不会对它们起作用. 考虑为您的提供者注册lambda并设置lambda中的所有内容: builder.Register(c => { var p = new SimpleAuthorizationServerProvider(); p.repository = c.Resolve<UserManager<IdentityUser>>(); // ...and so on return p; }).AsSelf().SingleInstance(); 另外,请记住,如果您注册一个实例(或注册一些东西作为SingleInstance,属性将被解析一次,那就是它.所以,如果你有一些依赖是InstancePerDependency或InstancePerRequest,那就不会按你想象的方式工作 – 他们将被解决一次,之后有效地成为单身人士. 更新1 基于原始和更新的代码,我发现如果您可以查看一些Autofac文档以更好地了解它是如何工作的,那将是一件好事.例如,使用SimpleAuthorizationServerProvider中的字段表明您可能无法完全了解注入如何在Autofac中工作或如何正确注册事物,因此Autofac可以为您完成工作. > Registration concepts 例如,查看更新… >您现在已经为SimpleAuthorizationServerProvider注册了lambda,但是我没有看到您在那里设置存储库字段的位置. 此外,您正在显示正在初始化的两个不同版本的OAuthServerOptions,并且很难分辨哪个版本是“真实的”. 我会建议一个相当重要的重构,以使事情能够正确地使用DI. 更改SimpleAuthorizationServerProvider以停止使用公共字段并将它们添加为构造函数参数,以便Autofac可以为您填充这些内容. public class SimpleAuthorizationServerProvider { public IAuthRepository Repository { get; private set; } public UserManager<IdentityUser> UserManager {get; private set; } public AuthContext Context { get; private set; } public SimpleAuthorizationServerProvider( IAuthRepository repository,UserManager<IdentityUser> userManager,AuthContext context) { this.Repository = repository; this.UserManager = userManager; this.AuthContext = context; } } 在启动期间,修复您的注册以删除多余的内容并利用Autofac自动布线优势. public class StartUp { public void Configuration(IAppBuilder app) { var config = new HttpConfiguration(); WebApiConfig.Register(config); var builder = new ContainerBuilder(); builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); // Register the auth context instance but skip // the extra .AsSelf() and .SingleInstance() because // it's implicit. builder.RegisterInstance(new AuthContext()); // Use the lambda to resolve the auth context rather // than making a closure over an instance. builder.Register(c => new UserStore<IdentityUser>(c.Resolve<AuthContext>())) .As<IUserStore<IdentityUser>>(); // Just register the provider type and let Autofac // do the work without all this manual stuff. Skip // the .AsSelf() because it's implicit if you don't // specify other interfaces and don't auto-wire properties // because you don't need it. builder.RegisterType<SimpleAuthorizationProvider>(); // This is fine,but I can't tell where it's used - if // you are using it at app startup or OUTSIDE a request,// you will get that exception you noted. Also,unless // you're actually using property injection,lose the // .PropertiesAutowired() call. builder.RegisterType<AuthRepository>() .As<IAuthRepository>() .InstancePerRequest() .PropertiesAutowired(); var container = builder.Build(); var resolver = new AutofacWebApiDependencyResolver(container); config.DependencyResolver = resolver; app.UseAutofacMiddleware(container); app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); app.UseWebApi(config); ConfigureOAuth(app,resolver); } public void ConfigureOAuth(IAppBuilder app,AutofacWebApiDependencyResolver resolver) { var options = new OAuthAuthorizationServerOptions() { AllowInsecureHttp = true,// If you want the values to be wired up,you have // to do a resolve. Note,however,that since you're // doing this wire-up at app startup,there's no request // scope,so if something in here is registered `InstancePerRequest` // you will get an exception. Provider = resolver.GetService(typeof(SimpleAuthorizationServerProvider)) as SimpleAuthorizationServerProvider }; app.USEOAuthAuthorizationServer(options); app.USEOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); } } 假设所有代码都应该没问题.如果没有设置东西 – 就像SimpleAuthorizationServerProvider属性中的一个属性为null,或者因为它缺少依赖项而得到异常,或者如果你得到关于没有请求范围的异常……那么还有其他东西要去你没有提出你的问题. 再次,请花时间查看文档并熟悉Autofac.我认为你遇到的许多麻烦都是因为对事情的联系有些误解. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- FluentSecurity是否取代了Asp.Net会员提供商,或者它应该与它
- asp.net – .Net System.Mail.Message添加多个“To”地址
- [译]ASP.NET Core 2.0 网址重定向
- ASP.NET中的自动机器密钥生成
- asp.net-mvc – ASP.NET MVC SiteMap提供程序 – 如何在实际
- asp.net – GridView:点击按钮获取行的数据键
- ASP.Net web api Vs .Net核心web api
- 禁用ASP.Net ReportViewer控件上的分页
- asp.net-mvc-4 – 如何在MVC4中呈现远程ReportViewer aspx页
- 如何在使用MasterPage的ASP.NET Web窗体中设置服务器控件的