powered by simpleCommunicator - 2.0.38     © 2025 Programmizd 02
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / Иньекция DbContext
98 сообщений из 98, показаны все 4 страниц
Иньекция DbContext
    #40015123
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Стандартный паттерн использования DbContext в ASP.NET Core это его иньекция туда где он нужен. Сам DbContext при этом принято регистрировать как scoped (так по умолчанию).

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

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

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

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

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

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

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

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

Все что создается через ДиАй диспозится автоматически когда диспозится его скоуп. Это же испокон веков во всех контейнерах так. Сам проверь, убедись, если хочешь. И транзиент тоже.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40015356
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Иньекция DbContext
    #40015357
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
handmadeFromRu
у меня вот куча сервисов, но transient очень малое колво в регистрации. прям почти все это скоупы + не много синглетоны ну вообще мало transient

Значит, ты просто делаешь все неправильно. Потому что скоуп совсем не для того, чтобы автоматически что-то там "закрывать".
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40015369
handmadeFromRu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Иньекция DbContext
    #40015374
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Иньекция DbContext
    #40015375
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
В принципе, есть-то опция, чтобы регистрировать DbContext как transient


DbContext как бы по природе не совсем транзиентный :)
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40015382
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Иньекция DbContext
    #40015383
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
DbContext как бы по природе не совсем транзиентный :)

Практически все сценарии работы с ним в ASP.NET - "запросил -> изменил -> сохранил", а потом он уже становится не нужен. Если какая-то десктопная аппликуха, то там вполне может быть и по другому, но в вебе само по себе все считай транзитивное из-за его stateless натуры.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40015385
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Иньекция DbContext
    #40015386
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Практически все сценарии работы с ним в ASP.NET - "запросил -> изменил -> сохранил", а потом он уже становится не нужен. Если какая-то десктопная аппликуха, то там вполне может быть и по другому, но в вебе само по себе все считай транзитивное из-за его stateless натуры.


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

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

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

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


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

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

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

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

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

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

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

да я эт понимаю. схема то что я описал все равно работала так как учитывал что скоуп очищает диспосет
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40015623
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
hVostt
fkthat,

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

Почему?


Find() берёт из кеша :)


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


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

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


Да, всё верно, если другой сервис вызвал SaveChanges контекста, это сохранит все изменения контекста.

И это, разумеется, правильно. Ибо ты сохраняешь состояние.

То, как ты описал, выглядит как независимые изменения, в таком случае ты тупо идёшь против самой концепции контекста. Как бы идёшь в разрез роли компонента в проекте. Ибо это UOW, а он не может быть точечным и независимым в рамках всей операции (читай, запроса).

И с другой стороны, если SaveChanges у тебя вызывается на разных уровнях, это очень кривая архитектура. Сохранение должно быть строго в одном слое.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40015695
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,

Да лично я-то никогда на практике со scoped data context проблем не имел, но просто вижу возможность их поимения. Потому что, повторюсь, scoped это по сути нечто глобальное, к чему имееет доступ все что только можно. А что-то глобальное это всегда возможность выстрелить себе в ногу. Это-то мне и не нравится.

Вот, смотри, такой, допустим, воображаемый сценарий.

1) Сервис А добавляет в контекст запись о покупке
2) Сервис А вызывает сервис Б чтобы вычислить НДС
3) Сервис А добавляет НДС в запись о покупке
4) Сервис А сохраняет изменения через SaveChange

Выглядит все нормально. Но вот. Я как разработчик сервиса А не знаю, да и знать не хочу как внутри устроен сервис Б. И поэтому я в душе не ведаю, что сервис Б для чего-то и сам вызывает SaveChanges (кто его там знает, может он какой-то аудит вызовов в базу пишет) - и он в этом вполне прав, потому что его тоже не должно волновать, что и как я перед его вызовом делал. И при таком сценарии между п.2 и п.3 в БД окажется некорректная запись (с ценой, но без НДС), которую, между прочим, какой-то другой запрос может прочитать, т.к. другой запрос будет в другом скоупе и у него будет "чистый" датаконтекст.

С т.з. правильного использования UoW я пока вижу только такой вариант, чтобы над всеми этими сервисами ставить какой-то сервис-оркестратор, который будет заниматься только тем, что вызывать нужные сервисы, а потом одним махом делать общий "коммит" в виде вызова SaveChanges.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40015696
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
И это, разумеется, правильно. Ибо ты сохраняешь состояние.

Чего же тут правильного, если я вызывая какой-то сервис, который писал вообще не я, должен всегда думать: "а не сохранит ли он мне то моё, что я еще пока что сохранять еще не хочу". Это вообще нарушение всех принципов модульности и инкапсуляции.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40015837
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Вот, смотри, такой, допустим, воображаемый сценарий.

1) Сервис А добавляет в контекст запись о покупке
2) Сервис А вызывает сервис Б чтобы вычислить НДС
3) Сервис А добавляет НДС в запись о покупке
4) Сервис А сохраняет изменения через SaveChange


Проблема в п.4
Сервис А не должен сохранять изменения :)


fkthat
Выглядит все нормально. Но вот. Я как разработчик сервиса А не знаю, да и знать не хочу как внутри устроен сервис Б. И поэтому я в душе не ведаю, что сервис Б для чего-то и сам вызывает SaveChanges


И поэтому ни Б, ни В, ни кто-то ещё не должен отвечать за сохранение. Это логика подготовки изменений. Конечное решение принимается на самом верхнем уровне.

Ибо.

Если ты последовательно выполняешь сервисы А, Б, В... и т.д., и хочешь сохранить тогда и только тогда, когда все сервисы корректно отработали, ты хрен это сделаешь, если каждый сервис будет самовольно что-то там сохранять (совсем страх потеряли..)

Подумай над этим :)

Смысл UOW в том, что ты только в одном месте принимаешь конечно решение.
И для тестирования хорошо.

А ещё инетресней всё становится, когда ты переписал всё в функциональном стиле, где вообще за эффекты в виде сохранения чего-то там куда-то внутри сервисных функций, бьют ногами :)
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40015839
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
над всеми этими сервисами ставить какой-то сервис-оркестратор, который будет заниматься только тем, что вызывать нужные сервисы


Ну вообще, задача разработки не усложнять, а упрощать.
Сервис-оркестратор у тебя уже из коробки есть.

Это контроллер.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40015840
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
hVostt
И это, разумеется, правильно. Ибо ты сохраняешь состояние.

Чего же тут правильного, если я вызывая какой-то сервис, который писал вообще не я, должен всегда думать: "а не сохранит ли он мне то моё, что я еще пока что сохранять еще не хочу". Это вообще нарушение всех принципов модульности и инкапсуляции.


Ну и чем поможет transient здесь? Ну потеряешь ты вообще всякий контроль, чем лучше?
Какой-то левый сервис что-то там сохранит, а тебе это не надо, если на втором шаге условие не выполняется.
Что делать?
Ничего, грызть локоть.

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

Ничего я не потяряю. Мой сервис будет работать со своим экземпляром контекстьа. Другой сервис будет работать со своим. Это как локальные переменные vs глобальные - меняя локальную переменную я гарантированно ни на что что за пределами её видимости не повлияю, поэтом я не парюсь ни о том можно ли мне и как её менять и так же не парюсь о том, что кто-то без моего ведома её поменяет.

hVostt
Какой-то левый сервис что-то там сохранит,

Почему левый? Обычный сервис из проекта, который мне для моих целей из моего сервиса нужен. Или же уже сервисам нельзя вызывать другие сервисы?

Это еще очень напоминает известную замороку со вложенными транзакциями в SQL. Там из-за этого, если ты хочешь внутри SP делать транзакцию приходится ставить проверки не находишься ли ты уже внутри транзакции. По крайней мере, когда-то это было так.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40015929
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Ничего я не потяряю. Мой сервис будет работать со своим экземпляром контекстьа. Другой сервис будет работать со своим. Это как локальные переменные vs глобальные - меняя локальную переменную я гарантированно ни на что что за пределами её видимости не повлияю, поэтом я не парюсь ни о том можно ли мне и как её менять и так же не парюсь о том, что кто-то без моего ведома её поменяет.


Не совсем понял, нафига тебе это.

Давай абстрактно, вот есть POST-запрос.
В рамках запроса у тебя может выполняться ряд операций разных сервисов.

С точки зрения интерфейса, это _единая операция_, клиенту как бы плевать сколько у тебя там сервисов и вообще на все твои 100500 слоёв и сервисов положить.

Вся операция -- единое целое, они либо она полностью выполнится, либо отвалится с ошибкой.
Какие ты там собрался промежуточные сохранения использовать, для чего?
Зачем эти половинчатые изменения? :)

Как бы DbContext в скоупе идеально ложится на эту концепцию. На этом принципе выполнено огромное дохренища проектов, и первый раз слышу, чтобы кого-то это не устраивало :))
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40015930
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Это еще очень напоминает известную замороку со вложенными транзакциями в SQL. Там из-за этого, если ты хочешь внутри SP делать транзакцию приходится ставить проверки не находишься ли ты уже внутри транзакции. По крайней мере, когда-то это было так.


Ну так вот scoped контекст эту проблему решает.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016024
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Как бы DbContext в скоупе идеально ложится на эту концепцию. На этом принципе выполнено огромное дохренища проектов, и первый раз слышу, чтобы кого-то это не устраивало :))

Ну и где там SaveChanges происходит? В конце вызова контроллера? Смахивает на костыль какой-то.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016027
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
fkthat
Это еще очень напоминает известную замороку со вложенными транзакциями в SQL. Там из-за этого, если ты хочешь внутри SP делать транзакцию приходится ставить проверки не находишься ли ты уже внутри транзакции. По крайней мере, когда-то это было так.


Ну так вот scoped контекст эту проблему решает.

Как решает?
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016273
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
hVostt
Как бы DbContext в скоупе идеально ложится на эту концепцию. На этом принципе выполнено огромное дохренища проектов, и первый раз слышу, чтобы кого-то это не устраивало :))

Ну и где там SaveChanges происходит? В конце вызова контроллера? Смахивает на костыль какой-то.


ну давай на примере:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
...Controller
{
    ...SomeAction(...)
    {
        _service1.Operation();
        _service2.Operation();
        _service3.Operation();
        return Ok(...);
    }
}



в _service1 ты что-то сохранил, а на _service2 у тебя что-то бахнет, значит мы вылетим из действия с искаверканными данными в БД (по бизнесу).

норм?

это не костыль, это большая увесистая грабля с гранатой на ручке.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016274
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
hVostt
пропущено...


Ну так вот scoped контекст эту проблему решает.

Как решает?


DbContext это UOW.

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

Он не создан, чтобы тупо сейвить каждой изменение каждой фигни в проекте.
Это общее сохранение всей проделанной работы.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016275
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat,

Не, я могу конечно ошибаться в твоём случае.
Просто не понимаю пока сути проблемы..

Для меня transient DbContext это дичь :)
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016289
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Он не создан, чтобы тупо сейвить каждой изменение каждой фигни в проекте.
Это общее сохранение всей проделанной работы.

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

в _service1 ты что-то сохранил, а на _service2 у тебя что-то бахнет, значит мы вылетим из действия с искаверканными данными в БД (по бизнесу).

Если все три вызова должны быть одной транзакцией, значит их надо явно объединять в одну транзакцию. При твоем подходе, получается, что SaveChanges надо вообще куда-то в middleware выносить.

А, кстати, в твоем примере кода, если ничего-таки не бахнет, то кто SaveChanges будет делать?
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016397
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Вот. Теперь смотри. Я пишу компонент (сервис). Меня заботит только то, что этот сервис должен делать то, для чего он предназначен. Меня вообще не волнует и не должно волновать, кто, как, и в каком сценарии его использует. А теперь, откуда мне знать, что тот, кто его использует, или тот, кто использует того, кто его использует действительно сохраняет изменения.


Это нарушение SRP.
DbContext это абстракция, а не работа с БД.

Одна из задач этой абстракции, это UOW.

Другими словами, ты говоришь, что твой сервис хочет работать с БД изолировано. Значит у него либо должен быть свой собственный личный DbContext, о котором никто ничего не знает, никто с ним больше не работает и вообще понятия не имеет, либо работать с БД напрямую.

fkthat
Если все три вызова должны быть одной транзакцией, значит их надо явно объединять в одну транзакцию. При твоем подходе, получается, что SaveChanges надо вообще куда-то в middleware выносить.

А, кстати, в твоем примере кода, если ничего-таки не бахнет, то кто SaveChanges будет делать?


Если в контексте ASP.NET, то контроллер.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016398
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat,

И всё же. Может есть реальный кейс, с которым ты столкнулся? Я просто за все свои множество лет опыта никогда таких проблем не ловил, наверное потому что воспринимают DbContext именно так, как он был задуман :)
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016406
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Если в контексте ASP.NET, то контроллер.

Т.е. инжектить DbContext в контроллер?
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016407
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Другими словами, ты говоришь, что твой сервис хочет работать с БД изолировано.

Да, потому что иначе он просто не реюзабельный, потому что становится зависимым от того, что снаружи него и как оно само работает.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016408
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
И всё же. Может есть реальный кейс, с которым ты столкнулся? Я просто за все свои множество лет опыта никогда таких проблем не ловил:)

Я тоже, но я же с самого начала и написал, "не ловил, но вижу возможность поймать". Впрочем, один раз что-то было, связанное с использованием Attach, впрочем, я не сторонник его использования, т.ч. это, скорее, исключение.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016447
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
hVostt
Если в контексте ASP.NET, то контроллер.

Т.е. инжектить DbContext в контроллер?


Не совсем. Инжектить IUnitOfWork, который реализуется DbContext-ом.

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


Он и должен быть зависимым, DbContext это полная абстракция над хранилищем.

fkthat
Я тоже, но я же с самого начала и написал, "не ловил, но вижу возможность поймать". Впрочем, один раз что-то было, связанное с использованием Attach, впрочем, я не сторонник его использования, т.ч. это, скорее, исключение.


Ну если не ловил, зачем заморачиваться :)
Я вот не ловил, и даже не вижу проблем.

То о чём ты говоришь, выглядит примерно как:

— а что если вилкой в глаз тыкнуть, то что? давайте пробку на вилку оденем!
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016476
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Не совсем. Инжектить IUnitOfWork, который реализуется DbContext-ом.

Тоже плохо. Потому что IUnitOfWork это все равно DAL, а не BL.

fkthat
Он и должен быть зависимым.

Сервис, работа которого зависит от других сервисов, про которые он даже ничего не знает?

Отвлечемся вообще от БД и контекста. Допустим, у меня стек вызов сервисов А->B>C->D и оказывается, что поведение сервиса D зависитот того, что делал сервис A перед тем как вызвал B. Это уже не модульное приложение будет, а какая-то адова лапша.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016477
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вот смотри (как я расшифровываю подход Хвоста), само название Db Context делает его похожим на артефакты типа HttpContext и иже с ним. То есть вот у тебя запрос, он же скоуп, на него формируется HttpContext, DbContext еще какие-то контексты. Каждый из сервисов может модифицировать что-то в этом контексте, но закрытие и финальное решение по этим контекстам происходит именно в момент окончания работы со скоупом, ну в данном случае - это последние команды контроллера.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016485
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro
ну в данном случае - это последние команды контроллера.

А если он где-то в фильтре используется, или в middleware? Да и, как я уже писал, вызывать DAL прямо из контроллера это уже сама по себе хрень какая-то. А по-хорошему, если что-то шарится между разными компонентами, должно быть иммутабельно. Поскольку дбконтекст таковым не является, то от этого можно вполне ожидать какой-нибудь беды.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016509
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Да и, как я уже писал, вызывать DAL прямо из контроллера это уже сама по себе хрень какая-то.


Это не DAL, это UOW. UOW может реализовывать не только SaveChanges в DbContext-а, но выполнять любые другие завершающие операции: отправка сообщений в очередь, инициация событий, сохранение данных в другие репозитории.

Мыслить рамками, что DbContext это абсолютно вся работа с данными что есть -- вредно.
Это не так.

fkthat
А по-хорошему, если что-то шарится между разными компонентами, должно быть иммутабельно. Поскольку дбконтекст таковым не является, то от этого можно вполне ожидать какой-нибудь беды.


Именно является. Как я уже сказал, это UOW. Проблема в твоих рассуждениях, что ты за DbContext видишь какой-то маленький кусочек, но не видишь остального.

Ну и проблемы прям люто надуманные. Я не представляю что можно сделать, чтобы контекст в скоупе было плохим решением. Это надо ещё постараться. Ну и это признак явного говнокодища :)
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016510
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro
Ну вот смотри (как я расшифровываю подход Хвоста), само название Db Context делает его похожим на артефакты типа HttpContext и иже с ним. То есть вот у тебя запрос, он же скоуп, на него формируется HttpContext, DbContext еще какие-то контексты. Каждый из сервисов может модифицировать что-то в этом контексте, но закрытие и финальное решение по этим контекстам происходит именно в момент окончания работы со скоупом, ну в данном случае - это последние команды контроллера.


Всё верно.

Просто со времён развития идеи fat controller is evil, люди ушли в другую крайность, которая ещё хуже, чем жирные контроллеры.

Именно контроллер отвечает за правильную организацию обработки запроса. От слова контроллер же!
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016512
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
А если он где-то в фильтре используется, или в middleware?


И что? Не вижу никаких проблем. В фильтре или в миддлеваре вообще нужно избегать работы с DbContext. И действовать через разумные абстракции.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016519
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
В фильтре или в миддлеваре вообще нужно избегать работы с DbContext. И действовать через разумные абстракции.

А я и не сказал, что напрямую использовать. Он может использоваться через какой-либо сервис BL.

hVostt
Именно контроллер отвечает за правильную организацию обработки запроса. От слова контроллер же!

Контроллер отвечает за трансляцию HTTP-запроса в вызов сервиса(ов) BL и трансляцию ответа от BL в HTTP-ответ. Знать что-то о том, что лежит ниже BL он не имеет права.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016533
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
hVostt
В фильтре или в миддлеваре вообще нужно избегать работы с DbContext. И действовать через разумные абстракции.

А я и не сказал, что напрямую использовать. Он может использоваться через какой-либо сервис BL.


Ну фиг знает, может у тебя фильтр для записи в БД лога запросов.
И отсюда растут ноги у проблемы :)

Конечно, так делать нельзя, DbContext для таких задач не предназначен.

fkthat
Контроллер отвечает за трансляцию HTTP-запроса в вызов сервиса(ов) BL и трансляцию ответа от BL в HTTP-ответ. Знать что-то о том, что лежит ниже BL он не имеет права.


А он и не знает. Не вижу никаких противоречий
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016539
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt

Ну фиг знает, может у тебя фильтр для записи в БД лога запросов.
И отсюда растут ноги у проблемы :)
ьзя, DbContext для таких задач не предназначен.

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


ПОГОДИ!
А если _этот сервис_ в тайне от тебя в БД что-то пишет?
Что тогда?
При чём тут тогда DbContext? :)

И что он там такого может _изменить_, что повлияет на тебя? Я просто не понимаю. Это что вообще он там может такого сделать?

fkthat
Замени его на любой синглтон (или на скоупед, что тот же синглтон и есть, только для контекста), состояние которого кто угодно может поменять, и будет то же самое. Именно это мне и не нравится.


Всё же хотелось бы более приземлённых примеров, в области практики.
Мне на самом деле в архитектуре .NET, библиотек и решений много чего не нравится.
Я даже не представляю что должно случиться, чтобы мне всё-всё нравилось :)

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


Надо как-то немного конкретней выделить проблему.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016613
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
А если _этот сервис_ в тайне от тебя в БД что-то пишет?

Так пусть себе и пишет. Суть в том, что все при этом должно быть сделано так, чтобы меня, как потребителя этого сервиса это не волновало. Ты пользуешься кучей .NET API - а вдруг оно тоже что-то там куда-то пишет, что ты не знаешь - тебя это просто не волнует и все, т.к. оно если и пишет, то делает это так, что тебя не трогает.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016626
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Так пусть себе и пишет. Суть в том, что все при этом должно быть сделано так, чтобы меня, как потребителя этого сервиса это не волновало. Ты пользуешься кучей .NET API - а вдруг оно тоже что-то там куда-то пишет, что ты не знаешь - тебя это просто не волнует и все, т.к. оно если и пишет, то делает это так, что тебя не трогает.


Ну давай тогды IMemoryCache тоже сделаем транзиентным

Как я уже говорил, от общего DbContext в скоупе есть реальный профит. Именно так он рекомендуется к использованию. Теоретически это тоже объясняется одним предложением: DbContext это UOW.

Какие-то надуманные и высосанные из пальца проблемы, якобы кто-то другой в мой контекст влезет и что-то там сломает на практике совершенно не подтверждаются. Проект, который построен на EF уже по факту обладает довольно высокой связностью.

Давай я пример ещё приведу.
У тебя есть приложение на EF с контекстом.
Ты решил добавить себе фоновые службы, вынес в отдельное сервисное приложение, как полагается.
Взял хенгфаер.

Теперь зырь: https://github.com/sergezhigunov/Hangfire.EntityFrameworkCore

Намекаю на то, что задачи Hangfire никак не пересекаются с задачами твоего DbContext.
Значит это другой контекст.

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

Ага. Под каждый сервис БЛ будем заводить отдельный контекст и БД. Да что уж там - давай под каждый метод сервиса отдельный контекст.

Одна из идей севиса (компонента) это инкапсуляция, что значит, что он не должен никак взаимодействовать со "внешним миром" кроме как через свой интерфейс-контракт. Если он начинает менять какие-то объекты, которые разделяет с другими сервисами, то это уже нарушение инкапсуляции. Неспроста ведь глобальные переменные, а также out, и ref параметры считаются говнокодом (ну, кроме Try-Get шаблона, может быть). Ровно по той же причине. Меня вообще доставляет, когда я регулярно вижу, как всё подряд, не глядя регают в контейнере как singleton или scoped - байты, блин экономят, что ли.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016640
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat,

В упор не вижу, как нарушается инкапсуляция DbContext-а. Это ведь итак уже абстракция. Итак контракт. Давай ещё каждый отдельный компонент ЕДИНОГО приложения будет содержать свой драйвер БД, свой пул соединений, свою файловую систему, каждому классу по отдельной плашке памяти и т.д. и т.п. :)

Вот сколько мы дискутируем, я так и не увидел ни одного хоть отдалённо приближенному к границам реальности кейса, где была обнаружена проблема, которую ты решаешь :)

fkthat
Меня вообще доставляет, когда я регулярно вижу, как всё подряд, не глядя регают в контейнере как singleton или scoped - байты, блин экономят, что ли.


А почему нет? Вот у меня добрый десяток _изолированных_ компонентов используют DbContext в одном HTTP запросе. Мне что на обработку запроса десяток соединений к одной и той же БД создавать?

Инженерия это прежде всего компромисс. Все шаблоны и принципы -- это борьба со сложностью, а не религия.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016644
handmadeFromRu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну наверное все ж от задачи и в вебе эт приемлемо. вопрос что если тебе 2 варика надо что придется дописать.

меня лично вызывает не понятки что часто делпют репо + Uow поверх орм где по сути также репо и uow.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016645
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
handmadeFromRu
ну наверное все ж от задачи и в вебе эт приемлемо. вопрос что если тебе 2 варика надо что придется дописать.

меня лично вызывает не понятки что часто делпют репо + Uow поверх орм где по сути также репо и uow.


продвинутые пацаны юзают CQ(R)S и на эту тему не парятся :)
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016646
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
В упор не вижу, как нарушается инкапсуляция DbContext-а.

Да никак она не нарушается. Я уже сто раз повторил. Просто один компонент может влиять на поведение другого через data context. Жить с этим можно, но я, все-таки, не вижу в этом ничего хорошего.

hVostt
Мне что на обработку запроса десяток соединений к одной и той же БД создавать?

Еще скажи, что ты не слышал про connection pool и во времена ADO.NET делал один общий объект Connection на все приложение.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016647
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
продвинутые пацаны юзают CQ(R)S и на эту тему не парятся :)

А CQRS в базу аки спаситель пешком по воде ходит?
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016656
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Просто один компонент может влиять на поведение другого через data context. Жить с этим можно, но я, все-таки, не вижу в этом ничего хорошего.


Так это... я ж привёл пример с кешем. IMemoryCache, любой компонент может повлиять на любой, грохнуть данные по ключам, записать туда мусор. И примеров можно дофига привести.

Мы же как-то живём с вилками и ножами, не смотря на всю их смертельную угрозу :)

fkthat
ще скажи, что ты не слышал про connection pool и во времена ADO.NET делал один общий объект Connection на все приложение.


Ну так пул как бы не бесконечный ресурс :)
Например, под нагрузками 100-200K rpm и выше, ресурсами не разбрасываются, особенно с необъяснимым выхлопом.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016657
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
hVostt
продвинутые пацаны юзают CQ(R)S и на эту тему не парятся :)

А CQRS в базу аки спаситель пешком по воде ходит?


Так типа ты вообще не тащишь никакой XxxxxContext :)
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016659
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Ну так пул как бы не бесконечный ресурс :)
Например, под нагрузками 100-200K rpm и выше, ресурсами не разбрасываются, особенно с необъяснимым выхлопом.

Поэтому и best practice это избавляться от соединения как можно быстрее, чтобы оно в пул вернулось, а не тянуть его открытым через весь запрос (впрочем, к ЕФ это отношения не имеет, т.к. у него контекст соединение не держит при себе, а дергает только когда оно надо)
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016660
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Так это... я ж привёл пример с кешем. IMemoryCache, любой компонент может повлиять на любой, грохнуть данные по ключам, записать туда мусор.

Это какой-то черезжопный кеш. По нормальному кеш делается тонкой прослойкой декораторов, и его клиент (к примеру, сервис БЛ) прямого доступа туда не имеет.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016662
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Поэтому и best practice это избавляться от соединения как можно быстрее, чтобы оно в пул вернулось, а не тянуть его открытым через весь запрос (впрочем, к ЕФ это отношения не имеет, т.к. у него контекст соединение не держит при себе, а дергает только когда оно надо)


Эти правила как раз применимы к HTTP-запросу. Дальше дробить, это уже ебантяйство какое-то :)


fkthat
Это какой-то черезжопный кеш. По нормальному кеш делается тонкой прослойкой декораторов, и его клиент (к примеру, сервис БЛ) прямого доступа туда не имеет.


Это перпендикулярные вещи совершенно. Добавить кеширующий аспект к запросу это одно, оперировать ключом это другое.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016664
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat,

Опять таки "прямого доступа не имеет" -- и вообще закрытый до фанатизма в дупелину БЛ, зачастую являет собой совершенно не сопровождаемое решение, от которого хочется плакать.

Не забываем, что кроме уменьшения связанности, нужно думать о хорошей связности.

Когда у тебя в проекте 100500 интерфейсов на каждую херню, это уже не смешно.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016665
handmadeFromRu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
handmadeFromRu
ну наверное все ж от задачи и в вебе эт приемлемо. вопрос что если тебе 2 варика надо что придется дописать.

меня лично вызывает не понятки что часто делпют репо + Uow поверх орм где по сути также репо и uow.


продвинутые пацаны юзают CQ(R)S и на эту тему не парятся :)

а как CQRS поможет не шлепать репо и uow? не понимаю
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016666
handmadeFromRu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
hVostt
Ну так пул как бы не бесконечный ресурс :)
Например, под нагрузками 100-200K rpm и выше, ресурсами не разбрасываются, особенно с необъяснимым выхлопом.

Поэтому и best practice это избавляться от соединения как можно быстрее, чтобы оно в пул вернулось, а не тянуть его открытым через весь запрос (впрочем, к ЕФ это отношения не имеет, т.к. у него контекст соединение не держит при себе, а дергает только когда оно надо)

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

Опять таки "прямого доступа не имеет" -- и вообще закрытый до фанатизма в дупелину БЛ, зачастую являет собой совершенно не сопровождаемое решение, от которого хочется плакать.

Не забываем, что кроме уменьшения связанности, нужно думать о хорошей связности.

Когда у тебя в проекте 100500 интерфейсов на каждую херню, это уже не смешно.

Не закрытый БЛ, а прозрачное кеширование, когда БЛ кеша просто не видит. Кеширующий декоратор . И как это вообще связано с кол-вом интерфейсов не пойму. Декоратор он на то и декоратор, что имеет тот же интерфейс, что у декорируемого объекта.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016670
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
handmadeFromRu
а как CQRS поможет не шлепать репо и uow? не понимаю


так у тебя для публики команды и запросы
никто в репу не ходит, есть она там и или нет.

насчёт uow, по-хорошему нужен, но не обязателен, если структура логики позволяет
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016671
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
handmadeFromRu
чекал он не держит конекшен открытым. открывает закрывает по запросу.

Да, я об этом выше и написал.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016672
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Не закрытый БЛ, а прозрачное кеширование, когда БЛ кеша просто не видит. Кеширующий декоратор .


Декоратор это паттерн, если реализовывать в лоб, то это довольно уродливое решение.
Поэтому лучше говорить про аспекты.

fkthat
И как это вообще связано с кол-вом интерфейсов не пойму. Декоратор он на то и декоратор, что имеет тот же интерфейс, что у декорируемого объекта.


Я так понимаю, ты с кешем работаешь исключительно через декораторы? :)
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016675
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Декоратор это паттерн, если реализовывать в лоб, то это довольно уродливое решение.
Поэтому лучше говорить про аспекты.

Отличное решение. А аспект это считай синоним. При правильной работе с DI декоратор становится вообще невидимым. Инжектишь интерфейс и получаешь уже задекорированный согласно конфигурации DI объект. У меня для автофака было несколько кастомных расширений, которыми можно было через атрибуты декорировать интерфейсы/объекты разной валидацией, аудитом, обработкой исключений и т.п.

hVostt
Я так понимаю, ты с кешем работаешь исключительно через декораторы? :)

Конечно. Не напрямую же его вызывать, мешая либо логику, либо работу с данными и кеширование. Принцип SR.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016679
handmadeFromRu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
handmadeFromRu
а как CQRS поможет не шлепать репо и uow? не понимаю


так у тебя для публики команды и запросы
никто в репу не ходит, есть она там и или нет.

насчёт uow, по-хорошему нужен, но не обязателен, если структура логики позволяет

так я ж про другое имел изначально вот поголовно пишут repo+uow а тот же ef эт уже эта связка. также можно прокидывать в cqrs контектс напрямую но нынче модно абсракцию поверх орм на всякий
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016681
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Отличное решение. А аспект это считай синоним. При правильной работе с DI декоратор становится вообще невидимым. Инжектишь интерфейс и получаешь уже задекорированный согласно конфигурации DI объект. У меня для автофака было несколько кастомных расширений, которыми можно было через атрибуты декорировать интерфейсы/объекты разной валидацией, аудитом, обработкой исключений и т.п.


es )

fkthat
Конечно. Не напрямую же его вызывать, мешая либо логику, либо работу с данными и кеширование. Принцип SR.


Ну тогды ладно :)
У нас проектах кеш не только для чистых данных используется, но и много для чего ещё.
Хотя, глядя на единственный CRUD проджект, который у нас есть небольшой, там и правда не используется..
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016682
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
handmadeFromRu
так я ж про другое имел изначально вот поголовно пишут repo+uow а тот же ef эт уже эта связка. также можно прокидывать в cqrs контектс напрямую но нынче модно абсракцию поверх орм на всякий


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

А что в кеше кешировать-то можно кроме данных? Понятно, что можно его просто использовать еще как быстрый key-value store, но это уже как бы и не кеш будет, а просто store для данных. Да и в таком случае не напрямую же использовать опять-таки, а завернуть во что-то хорошо бы.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016690
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
А что в кеше кешировать-то можно кроме данных? Понятно, что можно его просто использовать еще как быстрый key-value store, но это уже как бы и не кеш будет, а просто store для данных. Да и в таком случае не напрямую же использовать опять-таки, а завернуть во что-то хорошо бы.


На кеше много чего интересного можно реализовать :)
Как бы, и зачастую проще заюзать IMemoryCache, чем городить город из декораторов.
Понимаю, что есть динамик кастл и прочие прикольные штуки, но это не молоток, чтобы теперь все-все задачи были гвоздями. Где-то уместно, где-то не очень.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016729
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt

На кеше много чего интересного можно реализовать :)
Как бы, и зачастую проще заюзать IMemoryCache, чем городить город из декораторов.
Понимаю, что есть динамик кастл и прочие прикольные штуки, но это не молоток, чтобы теперь все-все задачи были гвоздями. Где-то уместно, где-то не очень.

Так декоратор внутри себя и использует IMemoryCache или подобное - ты что же, думаешь, там в нем какой-то самодельный кеш, что ли.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016781
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Так декоратор внутри себя и использует IMemoryCache или подобное - ты что же, думаешь, там в нем какой-то самодельный кеш, что ли.


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

Точечно пилить декоратор это злостный оверхед.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016788
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Ну вообще, чаще всего уместно использовать IDistributedCache

Да хоть вообще обычный Dictionary - суть-то не в этом.
hVostt
Точечно пилить декоратор это злостный оверхед.

Он пилится за три минуты даже в пьяном угаре. Причем можно сделать базовый декоратор и сделать так, что при желании сменить кеш-провайдер менять надо будет только в одном месте. (впрочем, у нас использовали CacheManager - он уже сам по себе адаптер к любому провайдеру).

Декоратор он для того, чтобы 1) отделить код работы с кешем от кода и БЛ и ДАЛ в отдельное место. 2) сделать для БЛ кеш прозрачным - он вообще не будет знать, что он вызывает ДАЛ не напрямую, а через кеш.

Может, ты просто под декоратором что-то другое понимаешь?
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016792
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Декоратор он для того, чтобы 1) отделить код работы с кешем от кода и БЛ и ДАЛ в отдельное место. 2) сделать для БЛ кеш прозрачным - он вообще не будет знать, что он вызывает ДАЛ не напрямую, а через кеш.


1) он итак уже отделён в отдельном месте, называется это место IMemoryCache :)
2) вообще он должен знать, так как без нормальной инвалидации такой кеш приносит больше вреда, чем пользы

Я всё равно не поддерживаю идеалистические подходы, без зрелого и осознанного понимания что делаешь в каждом конкретном случае. Всё делать через декоратор -- такое себе утверждение.

Как бы вот есть отвёртка, есть шуруповёрт, есть пневматика. Для каждого случая, для каждой задачи больше подходит свой инструмент. Говорить, что теперь всё херачим шуруповёртом и гвозди забиваем -- ну хз )))
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016796
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Может, ты просто под декоратором что-то другое понимаешь?


Декоратор это структурный паттерн, это для организации структуры приложения.

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

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

Какая структура? Какие жрет ресурсы? Весь кеширующий код, который у меня в декораторе у тебя без декоратора будет в том же виде либо в БЛ, либо в ДАЛ. С тем же успехом можно сказать, что ДАЛ жрет ресурсы, а чтобы не жрал, его весь внутрь БЛ надо поместить. Ты стопудово под декоратором что-то свое понимаешь.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016827
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Какая структура? Какие жрет ресурсы? Весь кеширующий код, который у меня в декораторе у тебя без декоратора будет в том же виде либо в БЛ, либо в ДАЛ. С тем же успехом можно сказать, что ДАЛ жрет ресурсы, а чтобы не жрал, его весь внутрь БЛ надо поместить. Ты стопудово под декоратором что-то свое понимаешь.


Ты лучше расскажи как решаешь проблему с инвалидацией кеша на декораторах :)
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016828
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Деление на типы паттернов часто очень условное. Декоратор он для того, чтобы не изменяя интерфейс объекта менять тем или иным образом его поведение (в том числе и динамически в рантайме). А медиатор, например, относят к паттернам поведения, но его также можно отнести и к структурным (структуру-то приложения он тоже задает).


Почему условное-то? Вполне себе конкретное :)

Декоратор никоим образом не оказывает влияния на взаимодействие компонентов.
А медиатор это конкретное решение для обеспечения взаимодействие.
И я видел злоупотребление тем же медиатором.
Как видел злоупотребление декоратором.

Любую здравую вещь можно превратить в культ и пихать куда не следует.
В некоторым случаях смотришь на код, где декоратор на декораторе, и думаешь, уж лучше бы этот человек писал обычный лапшекод, чем эту жесть.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016898
fkthis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt

И я видел злоупотребление тем же медиатором.
Как видел злоупотребление декоратором.

Если в голове пусто, то злоупотребить даже морковным соком можно.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016929
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthis
hVostt

И я видел злоупотребление тем же медиатором.
Как видел злоупотребление декоратором.

Если в голове пусто, то злоупотребить даже морковным соком можно.


Ну вот! К вопросу о transient-ном DbContext, может не надо ломать контекст, чтобы не защащаться от злостных изменений?


Как бы если в голове пусто, то хоть привяжи ко лбу пенопласт, помешать разбить лоб это не поможет.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40016937
fkthis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt
Ну вот! К вопросу о transient-ном DbContext, может не надо ломать контекст, чтобы не защащаться от злостных изменений?

Ну вот, допустим у меня поверх ЕФ репы. А у репы по самой её сути один вызов - одна транзакция (либо прочитать, либо сохранить). На кой леший мне шарить контекст между ними, если я от этого ничего не выгадываю, а проблем поиметь могу? Расшаренный контекст может иметь смысл, когда действительно с ним, как с UoW работать (таки, правда, и не выяснили, кто этот UoW коммитить будет).
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40017003
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthis
Ну вот, допустим у меня поверх ЕФ репы. А у репы по самой её сути один вызов - одна транзакция (либо прочитать, либо сохранить). На кой леший мне шарить контекст между ними, если я от этого ничего не выгадываю, а проблем поиметь могу? Расшаренный контекст может иметь смысл, когда действительно с ним, как с UoW работать (таки, правда, и не выяснили, кто этот UoW коммитить будет).


Ну ты хоть покажи каких проблем ты там ожидаешь поиметь.
Я в упор не понимаю о каких проблемах ты говоришь.
Может ты с ними столкнулся в реале?

Потому что сейчас это похоже на проблему преждевременной эякуляции оптимизации.
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40017041
fkthis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt
Потому что сейчас это похоже на проблему преждевременной эякуляции оптимизации.

У меня все по-скаутски "будь готов"

Допустим, у тебя в приложении глобальная переменная, она проблем пока не создавала, но ты видишь, что совершенно спокойно можешь сделать её локальной. Ты это сделаешь, или же это тоже будет "преждевременный рефакторинг"?
...
Рейтинг: 0 / 0
Иньекция DbContext
    #40017209
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthis
У меня все по-скаутски "будь готов"

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


Займусь этим когда в этом возникнет необходимость.
Например, глобальная переменная может создать мне проблем для покрытия тестами -- там и сделаю то, что нужно.

А просто так заниматься бессмысленной работой смысла не вижу.

Твой пример -- яркий. Ты себе что-то вообразил и борешься с этим. Тысячи людей пользуют DbContext в скоупе и он так используется по примерам майкрософт, и всё хорошо.

У тебя вдруг с какого-то перепугу в голове стало плохо. Переклинило чтоли?
Ну если у тебя дофига свободного времени, и заняться больше нечем, переноси DbContext из скоупа в транзиент.

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


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