Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / Иньекция DbContext / 25 сообщений из 98, страница 1 из 4
04.11.2020, 04:09
    #40015123
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
Стандартный паттерн использования DbContext в ASP.NET Core это его иньекция туда где он нужен. Сам DbContext при этом принято регистрировать как scoped (так по умолчанию).

В принципе, не могу вспомнить, чтобы у меня случались какие-то проблемы с этим, но не оставляет ощущение, что в этом заложено что-то недоброе. Scoped компонент в ASP.NET Core это объект глобальный для всего HTTP request, т.е. со всеми возможными граблями глобального объекта (сторонние эффекты).

Я однажды предложил вместо DbContext инжектить его фабрику, но у всех, разумеется, тут же полыхнуло, типа: "Еще наши прадеды инжектили DbContext, а ты тут собрался оскорбить их память и могилы обосс..ть". Вот мне и интересно узнать - кто-нибудь делает инъекцию DbContext не напрямую?
...
Рейтинг: 0 / 0
04.11.2020, 21:08
    #40015328
handmadeFromRu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
ну я пробовал раньше делать дженерик репо + uow и ощущал что это велик какой то.
фабрика ты вроде как говоришт дело но тогда ты будешь отвечать за закрытие и обслуживание и где гарантиии что кто то из твоих прогеров не забудет про закрытие ручное( кто создал тот и мочит хороший тон) поэтому когда я пишу код лично я стараюсь прям в коде сделать ограничение по использованию чего либо чтоб след прогер минимально в ногу выстрелил, конечно эт не отменяет что можно удалить код. если мы говорим в концепции di то скоуп вполне себе модель.
если так судить то у тебя все что в скоупе реквеста "глобальное"
...
Рейтинг: 0 / 0
04.11.2020, 21:35
    #40015332
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
handmadeFromRu
тогда ты будешь отвечать за закрытие и обслуживание

Нет, если фабрика будет работать через тот же DI, то при выходе из скоупа все что она насоздавала будет тоже диспозиться. В принципе, есть-то опция, чтобы регистрировать DbContext как transient, но на существующем проекте это как бы слишком уж глобаное изменение и делать его рисковано.
...
Рейтинг: 0 / 0
04.11.2020, 21:42
    #40015334
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
handmadeFromRu
если так судить то у тебя все что в скоупе реквеста "глобальное"

Да как бы нет, любой объект DI действительно принадлежить какому-либо скоупу, но ведь если он зареган как transient, то для каждой инъекции создается новый инстанс, так что никакой глобальности - каждый зависимый объект получит свой собственный экземпляр зависимости.
...
Рейтинг: 0 / 0
04.11.2020, 21:59
    #40015337
handmadeFromRu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
fkthat

Нет, если фабрика будет работать через тот же DI, то при выходе из скоупа все что она насоздавала будет тоже диспозиться. В принципе, есть-то опция, чтобы регистрировать DbContext как transient, но на существующем проекте это как бы слишком уж глобаное изменение и делать его рисковано.

где эт написано что оно высвободится то? что то новая инфа прям.
...
Рейтинг: 0 / 0
04.11.2020, 22:01
    #40015338
handmadeFromRu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
fkthat

Да как бы нет, любой объект DI действительно принадлежить какому-либо скоупу, но ведь если он зареган как transient, то для каждой инъекции создается новый инстанс, так что никакой глобальности - каждый зависимый объект получит свой собственный экземпляр зависимости.

опять же нет.. если ты регаешь как transient кто будет закрывать? скоуп как раз для этого. у меня вот куча сервисов, но transient очень малое колво в регистрации. прям почти все это скоупы + не много синглетоны ну вообще мало transient
...
Рейтинг: 0 / 0
04.11.2020, 22:56
    #40015353
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
handmadeFromRu
где эт написано что оно высвободится то? что то новая инфа прям.

Все что создается через ДиАй диспозится автоматически когда диспозится его скоуп. Это же испокон веков во всех контейнерах так. Сам проверь, убедись, если хочешь. И транзиент тоже.
...
Рейтинг: 0 / 0
04.11.2020, 23:10
    #40015356
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
handmadeFromRu
опять же нет.. если ты регаешь как transient кто будет закрывать?

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
using System;
using Microsoft.Extensions.DependencyInjection;

ServiceCollection services = new();
services.AddTransient<Foo>();
using var provider = services.BuildServiceProvider();

using (var scope = provider.CreateScope())
{
    for (var i = 0; i < 7; i++)
    {
        scope.ServiceProvider.GetRequiredService<Foo>();
    }
}

public class Foo : IDisposable
{
    public void Dispose()
    {
        Console.WriteLine("Bye-bye!");
    }
}


...
Рейтинг: 0 / 0
04.11.2020, 23:12
    #40015357
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
handmadeFromRu
у меня вот куча сервисов, но transient очень малое колво в регистрации. прям почти все это скоупы + не много синглетоны ну вообще мало transient

Значит, ты просто делаешь все неправильно. Потому что скоуп совсем не для того, чтобы автоматически что-то там "закрывать".
...
Рейтинг: 0 / 0
05.11.2020, 00:01
    #40015369
handmadeFromRu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
fkthat

Все что создается через ДиАй диспозится автоматически когда диспозится его скоуп. Это же испокон веков во всех контейнерах так. Сам проверь, убедись, если хочешь. И транзиент тоже.

погоди ты говорил через фабрику а не di. если как к примеру в dryioc заюзать фитчу верни мне фабрику объектов да вызоветься а если ты нашлепал фабрику типо
Код: c#
1.
2.
3.
4.
5.
6.
7.
 public class FooFabric
        {
            public Foo Create()
            {
                return new Foo();
            }
        }


то нет
с transient был не прав. в голове шелкнуло наверное изза привычки dryioc , он подефлту Dispose интерфейсы не позволяет регистрировать как Transient.
...
Рейтинг: 0 / 0
05.11.2020, 00:21
    #40015374
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
fkthat
Стандартный паттерн использования DbContext в ASP.NET Core это его иньекция туда где он нужен. Сам DbContext при этом принято регистрировать как scoped (так по умолчанию).

В принципе, не могу вспомнить, чтобы у меня случались какие-то проблемы с этим, но не оставляет ощущение, что в этом заложено что-то недоброе. Scoped компонент в ASP.NET Core это объект глобальный для всего HTTP request, т.е. со всеми возможными граблями глобального объекта (сторонние эффекты).

Я однажды предложил вместо DbContext инжектить его фабрику, но у всех, разумеется, тут же полыхнуло, типа: "Еще наши прадеды инжектили DbContext, а ты тут собрался оскорбить их память и могилы обосс..ть". Вот мне и интересно узнать - кто-нибудь делает инъекцию DbContext не напрямую?


Ну вообще в рамках scoped (запроса) один экземпляр контекста -- это хорошо. Ибо транзакционность, ибо кеш первого уровня, и возможность на нескольких уровнях работать с полученным ентити. В одном месте получили, в другом записали.

Если у тебя будет transient, ты огребёшь проблем и потерю в производительности.

Другое дело, фабрика позволяет иметь более одного DbContext-а. Но это решается на уровне абстракции.

У нас на одном проекте есть инъекция DbContext через авто-фабрику IIndex (Autofac), решение связано как раз из-за наличия более одного DbContext-а.
...
Рейтинг: 0 / 0
05.11.2020, 00:22
    #40015375
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
fkthat
В принципе, есть-то опция, чтобы регистрировать DbContext как transient


DbContext как бы по природе не совсем транзиентный :)
...
Рейтинг: 0 / 0
05.11.2020, 00:51
    #40015382
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
hVostt
Если у тебя будет transient, ты огребёшь проблем и потерю в производительности.

Врят ли. Кстати, по производительности. Если ты сделаешь подряд запросы, типа
Код: c#
1.
2.
var client1 = _db.Clients.SingleOrDefault(c => c.Id == 42);
var client2 = _db.Clients.SingleOrDefault(c => c.Id == 42);


То объект тебе вернет один и тот же, но у тебя все равно будет два запроса к БД, т.е. кеша все равно нет.

hVostt
У нас на одном проекте есть инъекция DbContext через авто-фабрику IIndex (Autofac)

Всегда нравилась эта его фича. Особенно с инжектом Func<IService> - там даже фабрики в большинстве случаев не надо.
...
Рейтинг: 0 / 0
05.11.2020, 00:57
    #40015383
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
hVostt
DbContext как бы по природе не совсем транзиентный :)

Практически все сценарии работы с ним в ASP.NET - "запросил -> изменил -> сохранил", а потом он уже становится не нужен. Если какая-то десктопная аппликуха, то там вполне может быть и по другому, но в вебе само по себе все считай транзитивное из-за его stateless натуры.
...
Рейтинг: 0 / 0
05.11.2020, 01:33
    #40015385
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
fkthat
Врят ли. Кстати, по производительности. Если ты сделаешь подряд запросы, типа
Код: c#
1.
2.
var client1 = _db.Clients.SingleOrDefault(c => c.Id == 42);
var client2 = _db.Clients.SingleOrDefault(c => c.Id == 42);



Тут программист сам должен понимать, что конкретно такой запрос выполнится дважды.

Если у тебя прокси-ентити, то обращения по навигационной сущности не будут запрошены дважды.
Если ты обращаешься к справочникам нормальным образом через Find(...), то каждая единица будет запрошена только один раз, а загруженные ранее в любом качестве не будут запрошены из БД, а взяты из кеша.

Если у тебя сложная логика работы с сущностями, то кеш довольно большую роль играет.

Но самое главное, если ты будешь работать с транзиентом, тебе придётся атачить ранее полученные сущности из других экземпляров контекста, иначе нарвёшься на грабли.

Так и не понял, а какие проблемы со скоупом? :)
...
Рейтинг: 0 / 0
05.11.2020, 01:35
    #40015386
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
fkthat
Практически все сценарии работы с ним в ASP.NET - "запросил -> изменил -> сохранил", а потом он уже становится не нужен. Если какая-то десктопная аппликуха, то там вполне может быть и по другому, но в вебе само по себе все считай транзитивное из-за его stateless натуры.


Не вопрос, всё верно. Но в рамках запроса у тебя может быть несколько действий с БД.
ДбКонтекст это же не только транслятор LINQ=>SQL.
Если тебе именно транлятор нужен, то EF выбор так себе.
...
Рейтинг: 0 / 0
05.11.2020, 01:36
    #40015387
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
fkthat,

Вообще, за SingleOrDefault по айдишнику нужно бить по пальцам :)
Всегда нужно использовать Find(), прям железно.
...
Рейтинг: 0 / 0
05.11.2020, 08:28
    #40015418
handmadeFromRu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
тот не ловкий момент с трансет я думал чутка не так но работает все) капец как стыдно
...
Рейтинг: 0 / 0
05.11.2020, 09:01
    #40015426
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
hVostt
fkthat,

Вообще, за SingleOrDefault по айдишнику нужно бить по пальцам :)
Всегда нужно использовать Find(), прям железно.

Почему?
...
Рейтинг: 0 / 0
05.11.2020, 09:06
    #40015427
vb_sub
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
Фабрика по определению решает совершенно другие проблемы-неопределенность получения конкретного типа DbContext в рантайме.
Вышеуказанной проблемы у ТС нет. Инъекция фабрики, которая выдаст DbContext вместо самого DbContext это просто добавление еще ненужного слоя абстракции.
Хотя возможно ТС хочет, чтобы фабрика выдавала или Scoped или Transient экземпляр? Просьба более подробно раскрыть этот момент.
...
Рейтинг: 0 / 0
05.11.2020, 09:17
    #40015430
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
hVostt
Не вопрос, всё верно. Но в рамках запроса у тебя может быть несколько действий с БД.
ДбКонтекст это же не только транслятор LINQ=>SQL.
Если тебе именно транлятор нужен, то EF выбор так себе.


1) Сервис А использует контекст и вызывает сервис Б, сервис Б тоже использует контекст, но не знает (и не должен ничего знать) про сервис А, т.к. инкапсуляция, single responsibility и все такое. И, понятно, что он тем более не знает что там перед ним сервис А с контекстом натворил. Запросто можно нарваться на какие-нибудь неожиданности.

2) Сервис А использует контекст и вызывает сервис Б. Сервис Б использует контекст и сохраняет свои изменения. Если сервис А перед вызовом Б внес свои изменения и еще не сохранял, то сервис Б сам того не ведая сохранит и их тоже и это как-то некрасиво.

В общем, глобальный объект это глобальный объект, от того что его назвали красивым словом "scoped" он глобальным быть не перестал, разве что его "глобальность" несколько ограничили.
...
Рейтинг: 0 / 0
05.11.2020, 09:21
    #40015431
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
vb_sub
Хотя возможно ТС хочет, чтобы фабрика выдавала или Scoped или Transient экземпляр? Просьба более подробно раскрыть этот момент.

Я хочу (или, лучше сказать, мне это кажется более правильным), чтобы каждый отдельный сервис, вызываемый в пределах скоупа, получал свой собственный экземпляр контекста, а не фигачил все свои изменения/сохранения в общий, рискуя нарваться на какие-либо конфликты с другими сервисами, вызываемыми в этом же скоупе.
...
Рейтинг: 0 / 0
05.11.2020, 09:35
    #40015435
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
hVostt
Но в рамках запроса у тебя может быть несколько действий с БД.

Я бы лучше сказал "в рамках вызова сервиса". Потому что если несколько взаимосвязанных запросов раскиданы по нескольким сервисам, то это вообще какой-то говнодизайн, нарушается весь loose coupling. А если в рамках одного вызова сервиса, то какие проблемы - получи контекст, сделай там хоть стопятьсот запросов и изменений, потом все одним разом сохрани - обычный Unit of work. И вот, кстати цикл работы с UoW (загрузи -> измени -> сохрани) это по сути отдельная логическая транзакция (не зря ведь его назвали "unit"). И существует очень общее правило: "при завершении (коммит/роллбек) транзакция забывает свое состояние". Т.е. любая транзакция никогда не должна использовать данные полученные в другой транзакции. А шейринг контекста между сервисами это правило нарушает.
...
Рейтинг: 0 / 0
05.11.2020, 09:43
    #40015438
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
handmadeFromRu
тот не ловкий момент с трансет я думал чутка не так но работает все) капец как стыдно

Тут, на самом деле, есть еще подводный камень, про который надо помнить - даже транзитивный объект живет все время жизни скоупа в котором он создан. В ASP.NET это проблем не создает, т.к. сами скоупы все короткоживущие, но, скажем, в каком-нибудь десктопном приложении это следует учитывать.
...
Рейтинг: 0 / 0
05.11.2020, 09:53
    #40015440
handmadeFromRu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Иньекция DbContext
fkthat
handmadeFromRu
тот не ловкий момент с трансет я думал чутка не так но работает все) капец как стыдно

Тут, на самом деле, есть еще подводный камень, про который надо помнить - даже транзитивный объект живет все время жизни скоупа в котором он создан. В ASP.NET это проблем не создает, т.к. сами скоупы все короткоживущие, но, скажем, в каком-нибудь десктопном приложении это следует учитывать.

да я эт понимаю. схема то что я описал все равно работала так как учитывал что скоуп очищает диспосет
...
Рейтинг: 0 / 0
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / Иньекция DbContext / 25 сообщений из 98, страница 1 из 4
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]