Как стать автором
Обновить
157
0
Pavel B. Novikov @pnovikov

.NET-разработчик

Отправить сообщение

Не секрет: это должно воздействовать на круг чрезмерно серьёзных читателей, которые потребуют от меня маркетингового буклета про мой фреймворк, сравнительного анализа подходов, метрик, планов по интеграции в существующие приложения, примеры success story на живых проектах и сильно разочаруются, когда узнают что всего этого пока ещё нет.


Разработка сейчас медленно перекатывается из стадии "proof of concept" на стадию "early adopters" и вкладываться в вышеперечисленные вещи ещё не время.


Заголовок с намеренными терминологическим кринжем сразу снижает градус серьёзности обсуждения, оставляя внимание только концептуально заинтересованных людей, которым интересно посмотреть на эксперимент (например, вас). На данный момент мне приоритетно работать именно с ними. Защищаться от нападок в жанре "а где примеры реального использования?!!" я пока не готов и не хочу тратить ни своё ни чужое время на это.


Как-то так. Извините, если грубовато.

Всё так, но не совсем.


Если вы используете O/RM как аспект, как соглашение, как подход — вы не можете отменить сам подход. Но переключить его реализацию — вполне можете. Идея в том, чтобы чётко разделять подход, внешнюю систему, которая этот подход приемлет и адаптер, который этот подход реализует для внешней системы.


LINQ — часть стандартной поставки .NET и это просто способ строить запросы. А вот способ ИСПОЛНЯТЬ эти запросы явно задаётся отдельно и его можно переключать.


Способ хранения при этом как раз не принципиален и его можно легко изменить. Ближайшая аналогия — это как интерфейс, у которого фиксированный набор методов, но может быть разная реализация.


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


Вот как-то так, только подход я называю аспект.

Как я вас понимаю…
(я не шучу, поглядите в мои публикации).

Это кринж :) Он делается чтобы было стыдно читателю.

В конце статьи я прямо выражаю благодарность fillpackart и его сообществу за помощь с редактурой и оформлением. Идею картинок с кодом в качестве иллюстраций я тоже украл у него. Только он любит Rider, а я — Visual Studio

Higher Kinded Types. Когда тип-параметры считаются полноценной частью языка, их можно собирать в массивы, фильтровать, группировать. В C# есть where-constraint-ы, но их мощности маловато. Дискуссию о том, что ожидают от них в C# можно почитать, например тут. Там же по ссылке приводят меткий термин: generics on generics.


Аналогию можно провести с higher kinded functions. В C# есть их поддержка через делегаты. С их помощью методы можно запихивать в переменные, собирать их в список, итерироваться по ним, передавать аргументами. Без них методы были бы просто методами. Вот хочется такой же гибкости, но на тип-параметрах.

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


Но если речь идёт о несложных задачках на алгоритмы или системный дизайн — то вполне норм. Ну или как вариант можно давать заранее заготовленный проект с открытыми местами для дописывания логики/фикса бага или что вас там интересует.

Почему бы кстати не предоставлять на собеседовании для решения задач самый быстрый компьютер с самой лучшей IDE но без интернета?


Сам делю разработчиков на "авторов своего" и "сборщиков из готового". Последних недолюбливаю.

При создании корневого инстанса есть возможность подпихнуть свой Transaction Manager, создающий транзакции на разных этапах процесса и на выбранных вами каналах. Не очень удобно — придётся обернуть канальные транзакции в обёртки Tecture и отнаследоваться от Transaction Manager-а. Но сама возможность присутствует.

Чтобы был processing pipeline — надо чтобы было что процессить. А у нас команды и запросы :)

Да. В конфигурации таких приложений, как мне показала практика — лежат по сути параметры инстанцирования каналов. Конекшн стринг к базе, адрес очереди, кэша и всякое такое прочее. Эти настройки по сути нужны один раз при инстанцировании канала в терминологии Tecture и держать их всё время в контейнере нет необходимости.


Но если хочется — можно например сделать канал/аспект с настройками. Вай нот? В дизайн всё ещё вписывается :)

Согласен с вами, работы именно столько. Не уверен что стану её делать.

В данном конкретном случае сходу мне в голову приходят два костыля: или выкинуть один из инстансов в статическую переменную, но это создаст проблемы использования других фишек Tecture вроде тестирования.


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


Либо вообще не засовывать в Tecture ту часть, которая статическая (полагаю она меньше) и общаться с ней вне сервисов Tecture.


Но кейс интересный, учту.

Вопрос в том, какие каналы у вас живут и почему так долго. Вангую что где-то у вас сидит SignalR или что-то подобное.


Без проблем — берёте TectureBuilder и делаете два разных инстанса ITecture — один на долгую память, другой на запрос.


То есть инстанс, создаваемый TectureBuilder-ом можно воспринимать как модуль — пакет сервисов с одинаковым временем жизни. Просто вы не каждому ProductsService прописываете явно .InSingletonScope/.InstancePerRequest, а делаете это один раз, скопом для всего ITecture.

Я исхожу из


Лайфтаймы <...> всё равно во всех проектах одинаковые и прибиты гвоздями к лайфтайму подключений к базе (и остальным внешним системам).

Сервис создаётся в тот момент, когда он впервые понадобился и умирает (ну… у него есть диспоз, но умирать там шибко нечему) вместе со смертью корневого инстанса ITecture (он Disposable) и задействованным подключения ко всем каналам.


Если брать на примере web-проекта, то смерть всего там в основном происходит после завершения обслуживания запроса.

Да. Видимо мне стоило использовать термин DI вместо IoC, но как-то так повелось что под IoC-контейнерами я (и не только я) понимаю вполне конкретную методологию.


Я вообще не силён в терминах и думаю что из статьи это довольно очевидно :)

Я подразумеваю любой примитив, позволяющий сопоставить в run-time тип некого компонента с его экземпляром, абстрагирующий пользователя от управления временем жизни этого экземпляра. Как-то так.


Штука, которой можно сказать "дай мне печеньку", не заботясь о том, откуда печенька берётся, кто её создал и на чём её мне привезут.

Мы рождены чтоб сказку сделать былью :)


Но да, бывает грустненько.

Я тут надысь узнал про существование Belgrade ORM. Вот можно его попробовать воткнуть :) Но конструктор запросов — одна из самых сложных частей EF и если делать его с нуля, то я даже не знаю с какого боку кусать эту задачу.

Информация

В рейтинге
Не участвует
Откуда
Новосибирск, Новосибирская обл., Россия
Зарегистрирован
Активность