Получение внедрения зависимостей для работы с Entity Framework Core вне страницы Razor .cs - PullRequest
0 голосов
/ 24 декабря 2018

Это для ASP.Net Core 2.1 с использованием Razor с Entity Framework Core.

Мне кажется, вопрос в том, как определить ReadData в ConfigureServices методе?

Пыталисьпосмотрите на этот вопрос Внедрение зависимостей DbContext вне проекта MVC , но по-прежнему не удается заставить работать код.

Попытка настроить доступ к базе данных с помощью Entity Framework Core через другой класс, кроме страницы Razor.

В классе Startup в методе ConfigureServices у нас есть это (я думаю, что это устанавливает внедрение зависимости для Конструктора на страницах Razor .cs):

services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); 

//Add Dependency Injection references
services.AddScoped<IReadData, ReadData>();

Это страница Razor .cs, и она работает с конструктором;однако, мы хотели бы разделить просмотр базы данных на другой класс с именем 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);
    }
}

Вот класс ReadData:

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

Внедрение зависимостей, которое работает настраницы бритвы .cs здесь не будут работать.Например, в MyPageModel для этой строки:

private readonly ReadData readData = new ReadData();

жалуется, что параметр не назначен для обязательного параметра для ReadData класса.

НО, в ReadDataесли мы добавим конструктор цепочки следующим образом:

public ReadData() : this(new MyProject.Data.AppDbContext()) { }

, мы получим ошибку:

InvalidOperationException: для этого DbContext не настроен поставщик базы данных.Поставщик может быть настроен путем переопределения метода DbContext.OnConfiguring или с помощью AddDbContext в поставщике службы приложений.Если используется AddDbContext, то также убедитесь, что ваш тип DbContext принимает объект DbContextOptions в своем конструкторе и передает его базовому конструктору для DbContext.

Как получить внедрение зависимостей для работы в Entity Framework Coreв ReadData классе?

Ответы [ 2 ]

0 голосов
/ 24 декабря 2018

Ваш класс ReadData должен иметь контекст в своем конструкторе:

public ReadData(MyProject.Data.AppDbContext context)
{

}

И теперь вам нужно только внедрить этот класс в вашу модель:

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

Пусть DIКонтейнер занимается созданием ваших объектов для вас.

0 голосов
/ 24 декабря 2018

Просто введите IReadData в конструктор 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);
    }
}

Не создавайте экземпляр ReadData

ReadData readData = new ReadData ();

позвольте DI-контейнеру разрешить ваши зависимости при регистрации services.AddScoped<IReadData, ReadData>();

...