ASP.NET Identity2 和 DataContext 注入

ASP.NET Identity2 and DataContext Injecting

我有一个在 ASP.NET MVC 5 上工作的多层 Web 应用程序。 我使用业务层将基础设施 (DAL) 与 UI 完全分离。 任何时候 UI 功能需要 DAL 访问,它调用我的业务服务,业务服务完成它的工作,如果需要 returns 结果。

对于 IoC,业务服务被注入到 UI 项目中,基础设施使用 Ninject

注入到业务服务中

我需要我的 UI 项目对我的基础设施项目有 0 个引用,但是在使用 ASP.NET Identity 2 框架时,它需要对 ApplicationDbContext 的基础设施的引用.

有两个对我的基础设施项目的引用,一个来自 IdentityConfig.cs

var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));

另一个来自 Startup.Auth.cs 在

        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

解决这个问题的方法是什么?

这是我使用的架构架构:

接口和工厂方法将解决您的问题。每当你想创建对象时 - 使用简单的工厂 returns 你的对象的接口。每当您想从具体实现中抽象出来时 - 使用接口。

public class ApplicationDbContextFactory
{
    public static IApplicationDbContext Create(IOwinContext owinContext)
    {
        return ApplicationDbContext.Create(owinContext);
    }
}

非常感谢@Andrei M 的大力帮助和指导, 我按如下方式解决了这个问题:

第一步:我在我的域层中创建了一个 IDbContext 接口。 (因为从演示文稿我们无法访问我的基础设施层)

public interface IDbContext : IDisposable
{
}

第二步:在基础设施层的 ApplicationDbContext 中实现 IDbContext 接口。

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IDbContext

第三步:在我的项目中,唯一引用我的基础设施层的层是业务层。所以为了在表示层的 owin 启动 class 中使用我的 ApplicationDbContext,我需要在业务层中有一个工厂 class 来 return 我的 Db 上下文。

public static class DbContextFactory
{
    public static IDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

第四步:更改 Owin 启动 class 以在需要 DbContext 时使用 My DbContextFactory Class。

public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context, user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext(DbContextFactory.Create);  

最后一步:唯一剩下的就是更改 IdentityConfig.cs 以在其创建方法中不直接引用 ApplicationDbContext。

 public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    {
        var myUserStore = new UserStore<ApplicationUser>((IdentityDbContext<ApplicationUser>) context.Get<IDbContext>());
        var manager = new ApplicationUserManager(myUserStore);

实际上对于这一步我有两个解决方案,第一个是你在上面看到的(转换为 IdentityDbContext) 第二个是 Cast to DbContext。我不知道以后转换到 DbContext(在 System.Data.Entity 命名空间中)时是否会遇到任何问题,现在我使用第一个解决方案。