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

Time:12-04

I have used IdentityDbContext in my project. My database has some tables which are connected to each other (relational). I want to use Repository pattern. I declared all my Interfaces. Then, I tried to Implement them. The problem is that I cannot create an instance of IdentityAppContext, because the constructor needs an input parameter 'option'. How can I implement them?

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

CodePudding user response:

Presuming that the DbContext is registered with a DI Container in your Startup.cs file, using something like:

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

then adding the following in the same method as the above will register your repository in the same DI Container:

services.AddScoped<IPmRepository, PmRepository>();

Then in your repository:

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

Then, in your controller (which is also provided by the container), you should be able to request from the container an IPmRepository in the constructor:

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

Note that because IdentityAppContext and IPmRepository are registered in the same container as MyController, then the framework can automatically provide the parameters for the MyController constructor.

Further, when the PmRepository is being created for the Controller the container can look at the constructor parameters of PmRepository and see that it wants an IdentityAppContext, which can be provided automatically because its registered in the same container.

  • Related