Форум программистов, компьютерный форум, киберфорум
C#: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
3 / 3 / 1
Регистрация: 24.02.2024
Сообщений: 131
.NET 8

Подскажите с выбором варианта регистрации DbContext в DI

17.04.2024, 12:20. Показов 2601. Ответов 26
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день!

Есть приложение Blazor Server Side, используется как десктоп приложение.
Есть основной контекст AppDbContext, для пользовательских данных, которые выводятся через UI (.razor).
В приложении много фоновых задач, которые периодически обращаются к этому же контексту AppDbContex.

Во избежание проблем с DbContext использовать обычную регистрацию в DI как я понимаю не стоит.

Как безопасно, и без тормозов лучше использовать контекст в этом случае?

На сколько я понимаю, то нужно использовать пул, но вот что лучше фабрики или обычные контексты?

C#
1
2
        builder.Services.AddDbContextPool<AppDbContext>();
        builder.Services.AddPooledDbContextFactory<AppDbContext>();

И ещё подвопрос.
Если есть ещё один контекст SomeDbContext, но он с подстановкой connectionString, то есть строка подключения меняется, то в этом случае использование ТОЛЬКО фабрики пулов?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
17.04.2024, 12:20
Ответы с готовыми решениями:

Тесты с выбором варианта
Привет IT-mans. У меня проблема возникла. однажды я сделал программу-тесты по фотошопу простенькую. Сейчас мне нужно сделать прогу...

Задания с выбором варианта ответа
Подскажите, как мне сделать так чтобы в тесте были задания только с выбором варианта ответа? path =...

Программа с выбором варианта решения задачи.
Помогите решить 2 задачи. http://s61.***********/i171/0905/7f/24d839454b1c.jpg Нужно решить первую и третью, вторую смог сделать.

26
Эксперт .NET
 Аватар для Usaga
14364 / 9465 / 1360
Регистрация: 21.01.2016
Сообщений: 35,689
19.04.2024, 09:51
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от gazed Посмотреть сообщение
В любом случае DbContext внутри сервиса EFProductRepository будет жить пока живёт Worker, а это уже не единичное обращение к контексту.
Нет. Я же говорю: можно заинжектить в Worker не сам сервис, а ServiceLocator, определить область видимости нужную (хоть в рамках одного метода) и там запрашивать сервис. Можно в рамках одного метода 100500 контекстов запросить и все они будут задеспоузены раньше, чем сдохнет Worker.

Т.е. этот момент регулируется как твоей душе угодно. Другое дело, что надо инжектить ServiceLocator для подобных выходок.

Добавлено через 24 минуты
Вот, что я имел в виду:

Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using Microsoft.Extensions.DependencyInjection;
 
var services = new ServiceCollection();
 
services.AddSingleton<Worker>();
services.AddTransient<DbContext>();
 
var provider = services.BuildServiceProvider();
 
var worker = provider.CreateScope().ServiceProvider.GetService<Worker>();
 
class DbContext : IDisposable {
    public DbContext() {
        System.Console.WriteLine("Here comes new DbContext");
    }
 
    public void Dispose() {
        System.Console.WriteLine("Oh, I'am going to die");
    }
}
 
class Worker {
    public Worker(IServiceProvider locator) {
        using (var scope = locator.CreateScope()) {
            /*using*/ var ctx = scope.ServiceProvider.GetService<DbContext>();
        }
 
        using (var scope = locator.CreateScope()) {
            /*using*/ var ctx = scope.ServiceProvider.GetService<DbContext>();
        }
    }
}
1
3 / 3 / 1
Регистрация: 24.02.2024
Сообщений: 131
19.04.2024, 10:02  [ТС]
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
И да, у меня примеры не Blazor, а ASP.NET Core MVC. Но не суть...
Ну почему же не суть.
Это же просто webapi.
А я говорю о том, что в рамках жизни "контроллера" есть несколько обращений к репозиторию.

Цитата Сообщение от Usaga Посмотреть сообщение
ServiceLocator
Это "антипаттерн" который использовался в WPF?

upd
Цитата Сообщение от Usaga Посмотреть сообщение
Вот, что я имел в виду:
Нет, это не похоже как было в WPF.

Так может всё-таки фабрика DbContext внутри сервисов/репозиториев?

p.s. Если что, я не пытаюсь вас на чём-то подловить, я хочу раз и навсегда разобраться с этим DbContext и его сервисами/репозиториями.
0
Эксперт .NET
 Аватар для Usaga
14364 / 9465 / 1360
Регистрация: 21.01.2016
Сообщений: 35,689
19.04.2024, 10:19
Цитата Сообщение от gazed Посмотреть сообщение
Это "антипаттерн" который
По сути да. Но не такой уж зашкварный, чтобы вообще нигде и никогда не использовать.

Цитата Сообщение от gazed Посмотреть сообщение
Так может всё-таки фабрика DbContext внутри сервисов/репозиториев?
Это и есть фабрика. Только правильная. Учитывающая область видимости, сама вызывающая Dispose, когда надо (обрати внимание, что я закомментил using для контекста, но он всё равно в нужный момент диспоузится), сама разруливающая все зависимости. Какой смысл изобретать фабрику, когда всё нужное уже есть из коробки.
1
 Аватар для Andrey-MSK
3371 / 2257 / 388
Регистрация: 14.08.2018
Сообщений: 7,646
Записей в блоге: 4
19.04.2024, 10:27
Цитата Сообщение от gazed Посмотреть сообщение
А я говорю о том, что в рамках жизни "контроллера" есть несколько обращений к репозиторию.
Я же вам показывал как работает Transient
C#
1
using (Repository _repository = new Repository()) { _repository.GetAll(); }
Добавлено через 2 минуты
gazed, Вы получаете не ссылку на объект, а ссылку на внутренний механизм DI, который сам что надо запустит и остановит.

Добавлено через 3 минуты
Цитата Сообщение от gazed Посмотреть сообщение
Ну почему же не суть.
Потому что не суть. Уровень доступа к данным может использоваться где угодно без изменений, просто запустите сервис и он готов к работе.
1
3 / 3 / 1
Регистрация: 24.02.2024
Сообщений: 131
19.04.2024, 13:49  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Какой смысл изобретать фабрику, когда всё нужное уже есть из коробки.
Я имею в виду DbContextFactory, она тоже из коробки есть.

Но вообще понял, локатор можно во всяких Singleton Manager и т.д. использовать, в которых много зависимостей, передавая туда только одну, и управляя гибко lifetime сервисов, независимо от их lifetime регистрации.


Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Вы получаете не ссылку на объект, а ссылку на внутренний механизм DI, который сам что надо запустит и остановит.
Всегда думал что получаю объект.
Теперь ещё больше вопросов появилось

Добавил в конструктор логи создания Transient Repository, почему-то только один раз логи сработали (ну точнее сразу 2 раза) а обращений идёт много к этому Repository.
Выходит что получаю объект в конструкторе.
0
 Аватар для Andrey-MSK
3371 / 2257 / 388
Регистрация: 14.08.2018
Сообщений: 7,646
Записей в блоге: 4
19.04.2024, 14:02
Цитата Сообщение от gazed Посмотреть сообщение
Добавил в конструктор логи создания Transient Repository
Репозиторий
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System.Diagnostics;
using System.Linq;
 
namespace SportsStore.Models
{
    public class EFProductRepository : IProductRepository
    {
        private ApplicationDbContext _context;
 
        public EFProductRepository(ApplicationDbContext context)
        {
            _context = context;
 
            Debug.WriteLine("Repo ctor");
        }
 
        public IQueryable<Product> Products => _context.Products;
    }
}
Вывод Debug
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
Repo ctor
'SportsStore.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.4\Microsoft.CSharp.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [t].[Category]
FROM (
    SELECT DISTINCT [p].[Category]
    FROM [Products] AS [p]
) AS [t]
ORDER BY [t].[Category]
Repo ctor
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (1ms) [Parameters=[@__category_0='?' (Size = 4000)], CommandType='Text', CommandTimeout='30']
SELECT COUNT(*)
FROM [Products] AS [p]
WHERE [p].[Category] = @__category_0
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (4ms) [Parameters=[@__category_0='?' (Size = 4000), @__p_1='?' (DbType = Int32), @__p_2='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SELECT [p].[ProductID], [p].[Category], [p].[Description], [p].[Name], [p].[Price]
FROM [Products] AS [p]
WHERE [p].[Category] = @__category_0
ORDER BY [p].[ProductID]
OFFSET @__p_1 ROWS FETCH NEXT @__p_2 ROWS ONLY
Repo ctor
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [t].[Category]
FROM (
    SELECT DISTINCT [p].[Category]
    FROM [Products] AS [p]
) AS [t]
ORDER BY [t].[Category]
The thread '[Thread Destroyed]' (16308) has exited with code 0 (0x0).
The thread '[Thread Destroyed]' (22800) has exited with code 0 (0x0).
The thread '[Thread Destroyed]' (33524) has exited with code 0 (0x0).
The thread '[Thread Destroyed]' (22808) has exited with code 0 (0x0).
Repo ctor
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT COUNT(*)
FROM [Products] AS [p]
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (1ms) [Parameters=[@__p_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SELECT [p].[ProductID], [p].[Category], [p].[Description], [p].[Name], [p].[Price]
FROM [Products] AS [p]
ORDER BY [p].[ProductID]
OFFSET @__p_0 ROWS FETCH NEXT @__p_0 ROWS ONLY
Repo ctor
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [t].[Category]
FROM (
    SELECT DISTINCT [p].[Category]
    FROM [Products] AS [p]
) AS [t]
ORDER BY [t].[Category]
Repo ctor
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (0ms) [Parameters=[@__category_0='?' (Size = 4000)], CommandType='Text', CommandTimeout='30']
SELECT COUNT(*)
FROM [Products] AS [p]
WHERE [p].[Category] = @__category_0
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (0ms) [Parameters=[@__category_0='?' (Size = 4000), @__p_1='?' (DbType = Int32), @__p_2='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SELECT [p].[ProductID], [p].[Category], [p].[Description], [p].[Name], [p].[Price]
FROM [Products] AS [p]
WHERE [p].[Category] = @__category_0
ORDER BY [p].[ProductID]
OFFSET @__p_1 ROWS FETCH NEXT @__p_2 ROWS ONLY
Repo ctor
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [t].[Category]
FROM (
    SELECT DISTINCT [p].[Category]
    FROM [Products] AS [p]
) AS [t]
ORDER BY [t].[Category]
Repo ctor
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT COUNT(*)
FROM [Products] AS [p]
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (0ms) [Parameters=[@__p_0='?' (DbType = Int32), @__p_1='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SELECT [p].[ProductID], [p].[Category], [p].[Description], [p].[Name], [p].[Price]
FROM [Products] AS [p]
ORDER BY [p].[ProductID]
OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY
Repo ctor
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [t].[Category]
FROM (
    SELECT DISTINCT [p].[Category]
    FROM [Products] AS [p]
) AS [t]
ORDER BY [t].[Category]
Repo ctor
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (0ms) [Parameters=[@__category_0='?' (Size = 4000)], CommandType='Text', CommandTimeout='30']
SELECT COUNT(*)
FROM [Products] AS [p]
WHERE [p].[Category] = @__category_0
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (0ms) [Parameters=[@__category_0='?' (Size = 4000), @__p_1='?' (DbType = Int32), @__p_2='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SELECT [p].[ProductID], [p].[Category], [p].[Description], [p].[Name], [p].[Price]
FROM [Products] AS [p]
WHERE [p].[Category] = @__category_0
ORDER BY [p].[ProductID]
OFFSET @__p_1 ROWS FETCH NEXT @__p_2 ROWS ONLY
Repo ctor
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [t].[Category]
FROM (
    SELECT DISTINCT [p].[Category]
    FROM [Products] AS [p]
) AS [t]
ORDER BY [t].[Category]
The thread '[Thread Destroyed]' (34672) has exited with code 0 (0x0).
The thread '[Thread Destroyed]' (31624) has exited with code 0 (0x0).
The thread '[Thread Destroyed]' (32448) has exited with code 0 (0x0).
The thread '[Thread Destroyed]' (5724) has exited with code 0 (0x0).
The thread '[Thread Destroyed]' (16336) has exited with code 0 (0x0).
The program '[26916] SportsStore.exe' has exited with code 4294967295 (0xffffffff).
Перед каждым запросом создаётся новый объект репозитория.
1
Эксперт .NET
 Аватар для Usaga
14364 / 9465 / 1360
Регистрация: 21.01.2016
Сообщений: 35,689
19.04.2024, 14:38
gazed, lifetime-регистрация все равно продолжает влиять. Даже если ты руками скоуп задашь как я показал, то внутри этого скоупа продолжит действовать эта самая регистрация. Если сервис зарегистрирован как синглтон, то ты получишь тот же его экзепляр, что и без ручного управления скоупом. Тразиентный сервис так же будет в рамках скоупа новый создаваться.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.04.2024, 14:38

Минимизировать расположение 2 учеников в соответствии с выбором варианта
Петя и Вася — одноклассники и лучшие друзья, поэтому они во всём помогают друг другу. Завтра у них контрольная по математике, и учитель...

Создать Веб страницу, на которой есть форма с выбором варианта формирования матрицы
Создать Веб страницу, на которой есть форма с выбором варианта формирования матрицы (вручную или с помощью генератора случайных чисел),...

Создать Веб страницу, на которой есть форма с выбором варианта формирования матрицы
Создать Веб страницу, на которой есть форма с выбором варианта формирования матрицы (вручную или с помощью генератора случайных чисел),...

Модуль регистрации с выбором группы пользователей
Ребят ищу модуль регистрации с подобными возможностями, типо выбора профиля. Joomla 3.2.3 стоит)

Два варианта сборки! Подскажите какую выбрать!
Бюджет 1200-1300 евро. Заказывать буду на amazon.co.uk Цель - Игры, Видео монтаж. 1) Вариант: Мат. плата - Gigabyte...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
27
Ответ Создать тему
Новые блоги и статьи
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения: - добавлена многоязычность - добавлено снятие скриншотов - добавлено поддержание бафов хождения по воде (для жреца, дк и шамана) - и так, по. . .
Алиса нашла кучу ошибок компиляции и запуска в проекте, который без проблем компилировался и запускался)))
anaschu 30.06.2026
Я пока посмеюся, но завтра проверю. А вообще интерсно. Дал алисе файл, в котором точно нет ошибок компиляции и запуска, и попросил их найти. Нашла кучу))) Критические ошибки, мешающие компиляции и. . .
сукцессия 16. Общий обзор, в основном что бы другие ии поняли
anaschu 29.06.2026
# Передаточный документ: модель микоризной сукцессии (для нового чата) Этот документ предназначен для того, чтобы новый чат Claude мог продолжить работу без необходимости заново разбираться в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru