我使用AutoFac 3.5与WebApi Integration 3.3和Asp.Identity 2.0.1。问题是当我将 MyDbContext 指定为 InstancePerRequest 时,Asp.Net Identity存在问题。然后我得到了这种错误消息:
没有标记匹配的范围' AutofacWebRequest'从请求实例的范围中可见。这通常表示SingleInstance()组件(或类似场景)正在请求注册为每HTTP请求的组件。在Web集成下,始终从DependencyResolver.Current或ILifetimeScopeProvider.RequestLifetime请求依赖项,从不从容器本身请求。
我正在注册Asp Token提供商,如下所示:
public partial class Startup
{
static Startup()
{
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/token"),
RefreshTokenProvider = (IAuthenticationTokenProvider)GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IAuthenticationTokenProvider)),
Provider = (IOAuthAuthorizationServerProvider)GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IOAuthAuthorizationServerProvider)),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromHours(1),
AllowInsecureHttp = true
};
}
public void ConfigureAuth(IAppBuilder app)
{
app.UseOAuthBearerTokens(OAuthOptions);
}
}
AutoFac部分看起来像这样:
builder.RegisterType<MyDbContext>().As<DbContext>().InstancePerRequest();
builder.RegisterType<SimpleRefreshToken>().As<IAuthenticationTokenProvider>();
builder.Register(x => new ApplicationOAuthProvider(
"self",
x.Resolve<Func<UserManager<User>>>()).As<IOAuthAuthorizationServerProvider>();
有没有人解决过这个问题?我找到了这篇旧帖子ASP.net Identity, IoC and sharing DbContext
修改
此博客文章也有一个凌乱的解决方法http://blogs.msdn.com/b/webdev/archive/2014/02/12/per-request-lifetime-management-for-usermanager-class-in-asp-net-identity.aspx
答案 0 :(得分:4)
我能够通过从OwinContext内部获取AutofacWebRequest并解析UserManager来解决问题。
将IOwinContext传递给每个OwinMiddleware的Invoke方法。内部您可以找到Enviroment属性,它是包含大量信息的IDictionary,包括&#34; autofac:OwinLifetimeScope&#34;。 你可以得到这个LifetimeScope,它应该被标记为&#34; AutofacWebRequest&#34;因为它是为每个http请求创建的嵌套范围,并解析了您需要的对象类型。
我的实现看起来与此类似。注意我在UserManagerFactory中生成UserManager类的方式。
public class Startup
{
static Startup()
{
PublicClientId = "self";
UserManagerFactory = () =>
{
//get current Http request Context
var owinContext = HttpContext.Current.Request.GetOwinContext();
//get OwinLifetimeScope, in this case will be "AutofacWebRequest"
var requestScope = owinContext.Environment.ContainsKey("autofac:OwinLifetimeScope");
if (!owinContext.Environment.Any(a => a.Key == "autofac:OwinLifetimeScope" && a.Value != null))
throw new Exception("RequestScope cannot be null...");
Autofac.Core.Lifetime.LifetimeScope scope = owinContext.Environment.FirstOrDefault(f => f.Key == "autofac:OwinLifetimeScope").Value as Autofac.Core.Lifetime.LifetimeScope;
return scope.GetService(typeof(UserManager<Models.UserModel>)) as UserManager<Models.UserModel>;
};
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProviderCustom(PublicClientId, UserManagerFactory),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
}
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static Func<UserManager<Models.UserModel>> UserManagerFactory { get; set; }
public static string PublicClientId { get; private set; }
public void Configuration(IAppBuilder app)
{
var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<UserModelsConvert>().InstancePerApiRequest();
builder.RegisterType<UserStoreCustom>().As<IUserStore<Models.UserModel>>().InstancePerApiRequest();
builder.RegisterType<UserManager<Models.UserModel>>().InstancePerApiRequest();
//loading other projects
builder.RegisterModule(new LogicModule());
var container = builder.Build();
app.UseAutofacMiddleware(container);
//// Create the depenedency resolver.
var resolver = new AutofacWebApiDependencyResolver(container);
// Configure Web API with the dependency resolver
GlobalConfiguration.Configuration.DependencyResolver = resolver;
app.UseOAuthBearerTokens(OAuthOptions);
//extend lifetime scope to Web API
app.UseAutofacWebApi(GlobalConfiguration.Configuration);
//app.UseWebApi(config);
}
}
我希望这可以提供帮助。如果错过了什么让我知道。