ASP.net 身份、IoC 和共享 DbContext

Dou*_*nez 5 entity-framework autofac owin asp.net-identity asp.net-web-api2

有没有人成功地将 IoC 与 OWIN ASP.NET Identity 附加到与 WebApi(或 MVC)应用程序共享相同的 DbContext?

我希望如果 ASP.Net 身份加载用户,它会在与应用程序其余部分使用的相同 dbcontext 中加载。

(使用 AutoFac 作为 IoC - 但不介意其他容器的示例)

编辑:06/Jan/2014:更具体一点,当 ASP.Net 身份尝试使用 DbContext 时,它需要与应用程序的其余部分相同的 DbContext实例。否则,它将创建相同 DbContext 的两个实例。我已经在使用.PerHttpApiRequest()扩展程序了。

我发现的问题是,在设置 OWIN 类时,我找不到一种方法:1)将容器附加到 OWIN 管道;2) 告诉 OWIN 使用该容器解析它需要的类,以便它可以共享相同的范围(即 OAUthServerOptions 或任何其他可能包含其他依赖项的)

话虽如此,您如何设置解决上述两点的 ASP.Net Identity?

Exc*_*ted 3

编辑:根据评论添加实例化 OWIN 管道。

由于 ASP.NET Identity 使用的 IdentityDbContext 继承自 DbContext,因此您可以简单地创建自己的继承自 IdentityDbContext 的实现,如下所示

public class ApplicationContext : IdentityDbContext<ApplicationUser>
{
     //additional DbSets
    public DbSet<OtherEntity> OtherEntities { get; set; } 
}

public class ApplicationUser : IdentityUser
{
    //any custom properties you want for your user.
}

public class OtherEntity
{
    [Key]
    public int Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在就使用 IoC 而言,从统一的角度来看,我注册了一个 UserStore 实例,如下所示

public static void RegisterTypes(IUnityContainer container)
{
    container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new InjectionConstructor(typeof(ApplicationContext)));
}
Run Code Online (Sandbox Code Playgroud)

然后围绕用户管理器创建一个包装器

public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store) : base(store)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

并在我需要用户管理器的任何地方注入它。

对于 OWIN 管道,您需要通过容器实例化 OAuthAuthorizationProvider,如下所示。

container.RegisterType<IOAuthAuthorizationServerProvider, ApplicationOAuthProvider>(new InjectionConstructor("self", typeof(ApplicationUserManager)));
Run Code Online (Sandbox Code Playgroud)

那么例如在WebApi中,您只需在启动时从容器中获取实例即可。

static Startup()
        {
            OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/Token"),
                Provider = (IOAuthAuthorizationServerProvider)GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IOAuthAuthorizationServerProvider)),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(5),
                AllowInsecureHttp = true,
                RefreshTokenProvider = new SimpleRefreshTokenProvider()
            };
        }
Run Code Online (Sandbox Code Playgroud)