Bab*_*loo 4 autofac asp.net-web-api owin
在阅读有关使用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());
}
}
Run Code Online (Sandbox Code Playgroud)
但是在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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
你能帮帮我吗?
更新
如果在ConfigureOAuth方法中,我使用以下方法:
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = resolver.GetService(typeof(SimpleAuthorizationServerProvider)) as SimpleAuthorizationServerProvider
};
Run Code Online (Sandbox Code Playgroud)
我收到错误:
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.
Run Code Online (Sandbox Code Playgroud)
当您注册对象的实例而不是类型时,即使您指定PropertiesAutowired不会生效,因为Autofac假定您在创建实例时已完成所需的所有工作.如果要连接属性,则需要在OnActivated处理程序中执行此操作.
在这个示例代码中实际上有很多东西在起作用.
SimpleAuthorizationServerProvider是场没有性能等等PropertiesAutowired会不会对他们的工作.UserManager<IdentityUser>注册为lambda但也有PropertiesAutowired不起作用 - 您只能PropertiesAutowired在基于反射的组件上使用(例如RegisterType<T>).考虑为您的提供者注册lambda并设置lambda中的所有内容:
builder.Register(c => {
var p = new SimpleAuthorizationServerProvider();
p.repository = c.Resolve<UserManager<IdentityUser>>();
// ...and so on
return p;
}).AsSelf().SingleInstance();
Run Code Online (Sandbox Code Playgroud)
另外,请记住,如果你注册一个实例(或注册一些东西,因为SingleInstance属性将被解析一次,就是这样.所以,如果你有一些依赖,InstancePerDependency或者InstancePerRequest,这不会像你想象的那样工作 - 他们会在那之后得到解决,有效地成为单身人士.
更新1
基于原始和更新的代码,我发现如果您可以查看一些Autofac文档以更好地了解它是如何工作的,那将是一件好事.例如,在SimpleAuthorizationServerProvider演出中使用字段可能无法完全了解Autofac中的注入方式或如何正确注册事物,因此Autofac可以为您完成工作.
例如,查看更新...
SimpleAuthorizationServerProvider但我没看到你在哪里设置repository字段.PropertiesAutowired在SimpleAuthorizationServerProvider因为你注册的λ和属性不会被自动装配(如前所述)注册.InstancePerRequest是,AuthRepository但是,就像我说的那样,我看不出那个被解决或设置的地方 - 而且这是唯一会产生你注意到的异常的东西.有关于处理您应该研究的确切异常的常见问题解答.此外,您正在显示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;
}
}
Run Code Online (Sandbox Code Playgroud)
在启动期间,修复您的注册以删除多余的内容并利用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,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
// 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());
}
}
Run Code Online (Sandbox Code Playgroud)
假设所有代码都应该没问题.如果事情没有设置 - 就像其中一个SimpleAuthorizationServerProvider属性是null,或者你得到一个异常,因为它缺少一个依赖项,或者如果你得到关于没有请求范围的例外...那么还有其他事情发生你没有提出你的问题.
再次,请花时间查看文档并熟悉Autofac.我认为你遇到的许多麻烦都是因为对事情的联系有些误解.
| 归档时间: |
|
| 查看次数: |
4300 次 |
| 最近记录: |