如何在使用 IdentityDbContext 的情况下在 ASP.NET Core MVC 中使用存储库模式?

How to use repository pattern in ASP.NET Core MVC while IdentityDbContext has been used?

我在我的项目中使用了 IdentityDbContext。我的数据库有一些相互连接的表(关系)。我想使用存储库模式。我声明了我所有的接口。然后,我尝试实施它们。问题是我无法创建 IdentityAppContext 的实例,因为构造函数需要一个输入参数 'option'。 我该如何实施它们?

IdentityAppContext.cs :

public class IdentityAppContext: IdentityDbContext<AppUser, AppRole, int>
{
    public IdentityAppContext(DbContextOptions<IdentityAppContext> options) : base(options)
    {

    }
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
    }
    public DbSet<AppUser> Users { get; set; }
    public DbSet<Message> Messages { get; set; }
    public DbSet<PM> PMs { get; set; }
    public DbSet<Notification> Notifications { get; set; }
    public DbSet<FileRepository> Files { get; set; }
}

IPmRepository.cs :

public interface IPmRepository
{
    IEnumerable<PM> GetAllPMs();
    PM GetPmById(int pmId);
    bool InsertPM(PM pm);
    bool UpdatePM(PM pm);
    bool DeletePM(int pmId);
    bool DeletePM(PM pm);
    void Save();
}

PmRepository.cs :

public class PmRepository : IPmRepository
{
    IdentityAppContext db = new IdentityAppContext();
    public IEnumerable<PM> GetAllPMs()
    {
        
    }
    public PM GetPmById(int pmId)
    {
        throw new NotImplementedException();
    }
    public bool InsertPM(PM pm)
    {
        throw new NotImplementedException();
    }
    public bool UpdatePM(PM pm)
    {
        throw new NotImplementedException();
    }
    public bool DeletePM(int pmId)
    {
        throw new NotImplementedException();
    }

    public bool DeletePM(PM pm)
    {
        throw new NotImplementedException();
    }
    public void Save()
    {
        throw new NotImplementedException();
    }
}

假设 DbContext 已注册到 Startup.cs 文件中的 DI 容器,使用类似:

services.AddDbContext<IdentityAppContext>(opt => 
{
   opts.UseSqlServer(myConnectionString);
})

然后以与上述相同的方法添加以下内容将在同一个 DI 容器中注册您的存储库:

services.AddScoped<IPmRepository, PmRepository>();

然后在您的存储库中:

public class PmRepository : IPmRepository
{
    readonly IdentityAppContext _context;
 
    // 'context' parameter is automagically provided by the container.
    public PmRepository(IdentityAppContect context)
    {
        _context = context;
    }

    public bool InsertPM(PM pm)
    {
        _context.PMs.Add(pm);
    }
}

然后,在你的控制器(容器也提供)中,你应该可以在构造函数中向容器请求一个 IPmRepository:

public class MyController : Controller
{
    readonly IdentityAppContext _context;
    readonly IPmRepository _pmRepository;

    // Both 'context' and 'pmRepository' are automagically provided by the container
    public MyController(
        IdentityAppContext context,
        IPmRepository pmRepository)
    {
        _context = context;
        _pmRepository = pmRepository;
    }

    [HttpPost]
    public async Task DoSomething(MyRequest request)
    {
        _pmRepository.InsertPM(new PM() { Id = request.Id });

        await _context.SaveChangesAsync();
    }
}

注意,由于IdentityAppContext和IPmRepository都注册在MyController同一个容器中,所以框架可以自动为MyController的构造函数提供参数。

此外,当为控制器创建 PmRepository 时,容器可以查看 PmRepository 的构造函数参数,并看到它需要一个 IdentityAppContext,它可以自动提供,因为它在同一个容器中注册。