ASP.NET Identity2和DataContext注入

时间:2015-08-31 13:05:07

标签: c# asp.net-mvc asp.net-mvc-5 ninject asp.net-identity

我有一个使用ASP.NET MVC 5的多层Web应用程序。 我已经使用业务层将基础结构(DAL)与UI完全分离。 任何时候UI功能都需要DAL访问权限,它会调用我的业务服务,业务服务会执行它的工作,如果需要,则会返回结果。

对于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);

这是什么解决方案?

这是我使用的架构的架构:enter image description here

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

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

public interface IDbContext : IDisposable
{
}

第二步:在我的ApplicationDbContext中的Infrastructure Layer中实现IDbContext接口。

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IDbContext

第三步:在我的项目中,唯一引用我的基础架构层的层是业务层。所以为了在我的业务层中的owin启动类中使用我的ApplicationDbContext,我需要在我的业务层中使用Factory类来返回Db上下文。

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

Forth Step:在需要DbContext时,将Owin Startup类更改为使用My DbContextFactory类。

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);

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