Reputation: 363
This is for ASP.Net Core 2.1 using Razor with Entity Framework Core.
I think the question is how to define ReadData
in ConfigureServices
method?
Have tried to look at this question DbContext Dependency Injection outside of MVC project, but still cannot get code to work.
Trying to set up database access with Entity Framework Core through another class other than the Razor page.
In the Startup
class in the ConfigureServices
method we have this (I think this sets up the dependency injection for the Constructor in the Razor pages .cs):
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
//Add Dependency Injection references
services.AddScoped<IReadData, ReadData>();
This is a Razor .cs page and it works with the Constructor; however, we would want to separate the db look up into another class called ReadData
.
public class MyPageModel : PageModel
{
private readonly MyProject.Data.AppDbContext _context;
private readonly ReadData readData = new ReadData();
public MyPageModel(MyProject.Data.AppDbContext context)
{
_context = context;
}
public IList<Car> Cars { get;set; }
public async Task OnGetAsync()
{
var userName = User.FindFirst(ClaimTypes.Name).Value; // will give the user's userName
Prayer = await readData.FetchCars(userName);
}
}
Here's the ReadData
class:
public class ReadData : IReadData
{
private readonly MyProject.Data.AppDbContext _context;
public ReadData(MyProject.Data.AppDbContext context)
{
this._context = context;
}
public async Task<IList<Car>> FetchCars(string carOwner)
{
var cars = _context.Cars.Where(p => p.Owner == carOwner);
return await Task.FromResult(cars.ToList());
}
}
The dependency injection that works on the Razor .cs pages will not work here.
For example, in MyPageModel
for this line:
private readonly ReadData readData = new ReadData();
it complains that a parameter is not assigned for the required parameter for ReadData
class.
BUT, in ReadData
if we add chaining constructor like this:
public ReadData() : this(new MyProject.Data.AppDbContext()) { }
we get an error:
InvalidOperationException: No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions object in its constructor and passes it to the base constructor for DbContext.
How do we get dependency injection to work for Entity Framework Core in the ReadData
class?
Upvotes: 0
Views: 940
Reputation: 681
Just inject IReadData
on the constructor of MyPageModel
public class MyPageModel : PageModel
{
private readonly MyProject.Data.AppDbContext _context;
private readonly IReadData _readData ;
public MyPageModel(IReadData readData)
{
_readData = readData;
}
public async Task OnGetAsync()
{
var userName = User.FindFirst(ClaimTypes.Name).Value; // will give the user's userName
var Prayer = await _readData.FetchCars(userName);
}
}
Don't create instance of ReadData
ReadData readData = new ReadData();
let DI container resolve your dependencies as you registered services.AddScoped<IReadData, ReadData>();
Upvotes: 1
Reputation: 118937
Your ReadData
class should take a context in it's constructor:
public ReadData(MyProject.Data.AppDbContext context)
{
}
And now you only need to inject this class into your model:
public class MyPageModel : PageModel
{
private readonly IReadData _readData ;
public MyPageModel(IReadData readData)
{
_readData = readData;
}
public async Task OnGetAsync()
{
var userName = User.FindFirst(ClaimTypes.Name).Value; // will give the user's userName
var Prayer = await _readData.FetchCars(userName);
}
}
Let the DI container deal with creating your objects for you.
Upvotes: 4