Шаблон Full Stack FastAPI теперь отдаёт фронтенд на React и TanStack прямо через FastAPI.
В итоге одно приложение, один деплой и один домен.
Без отдельного фронтенд-сервера, лишней настройки CORS и постоянной отладки проблем между двумя частями приложения.
https://github.com/fastapi/full-stack-fastapi-template
👉 @KodBlog
В итоге одно приложение, один деплой и один домен.
Без отдельного фронтенд-сервера, лишней настройки CORS и постоянной отладки проблем между двумя частями приложения.
https://github.com/fastapi/full-stack-fastapi-template
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4🍾1
Пришло время что-то собрать.
В этом GitHub-репозитории собрана огромная коллекция практических руководств, где обучение идёт через создание реальных проектов.
Если застряли на вопросе «что вообще сделать?», начинать можно отсюда.
https://github.com/practical-tutorials/project-based-learning
👉 @KodBlog
В этом GitHub-репозитории собрана огромная коллекция практических руководств, где обучение идёт через создание реальных проектов.
Если застряли на вопросе «что вообще сделать?», начинать можно отсюда.
https://github.com/practical-tutorials/project-based-learning
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
GitHub - practical-tutorials/project-based-learning: Curated list of project-based tutorials
Curated list of project-based tutorials. Contribute to practical-tutorials/project-based-learning development by creating an account on GitHub.
🍾4❤1
IAsyncActionFilter недооценён, хотя это очень мощный инструмент.В ASP.NET Core фильтры позволяют запускать свою логику до или после определённых этапов обработки запроса, не трогая сами контроллеры.
Две главные причины их использовать
1. Повторное использование — одну и ту же логику можно применять сразу к нескольким контроллерам или действиям.
2. Расширяемость — бизнес-правила можно полностью вынести из методов контроллера.
IActionFilter выполняется до и после метода действия и хорошо подходит для лёгких синхронных проверок.IAsyncActionFilter нужен, когда внутри проверки приходится ждать асинхронную операцию — например, запрос к базе данных или другому сервису.Вместо двух отдельных методов до и после здесь используется один
OnActionExecutionAsync, который оборачивает вызов next().Если вызвать
next(), выполнение продолжится дальше. Если не вызывать его и задать context.Result, запрос можно остановить прямо в фильтре.internal sealed class EmailVerifiedFilter(
IUser currentUser,
IUserService userService) : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(
ActionExecutingContext context,
ActionExecutionDelegate next)
{
Guid? userId = currentUser.Id;
if (userId != null &&
!await userService.IsEmailVerifiedAsync(userId))
{
context.Result = new ForbidResult();
return;
}
await next();
}
}
Регистрация
builder.Services.AddScoped<EmailVerifiedFilter>();
Использование
[HttpGet("dashboard")]
[ServiceFilter(typeof(EmailVerifiedFilter))]
public IActionResult GetUserDashboard()
{
...
}Хорошо подходит для проверки подтверждения почты или подписки, выполнения бизнес-правил перед запуском действия, условной блокировки запросов и любой общей логики, которую иначе пришлось бы копировать в десяток контроллеров.
Но если нужна обычная проверка роли или политики без обращения к базе данных, чаще лучше использовать
IAsyncAuthorizationFilter. Он выполняется ещё до привязки модели, поэтому отклонённый запрос не тратит ресурсы на ненужную работу.Один фильтр — куча сценариев.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🍾1
SignalR позволяет добавлять функции реального времени в приложения на .NET.
И всё начинается с SignalR Hub.
Hub — это центральный компонент приложения, который управляет подключёнными клиентами и отправкой сообщений. Чтобы получать и отправлять сообщения, клиенты должны подключиться к Hub.
SignalR — одна из лучших библиотек в экосистеме .NET.
👉 @KodBlog
И всё начинается с SignalR Hub.
Hub — это центральный компонент приложения, который управляет подключёнными клиентами и отправкой сообщений. Чтобы получать и отправлять сообщения, клиенты должны подключиться к Hub.
SignalR — одна из лучших библиотек в экосистеме .NET.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🥰3🍾1
Эндпоинт работает медленно. В логах написано, что запрос занял 800 мс. И что дальше?
Одних логов недостаточно, чтобы понять, куда ушло время. Это был обработчик? Запрос к базе данных? Внешний вызов? В итоге приходится гадать или добавлять Stopwatch, снова разворачивать приложение и проверять ещё раз.
Именно поэтому в моём шаблоне полная картина доступна сразу.
Приложение отправляет логи, трассировки и метрики через OTLP. Один контейнер grafana/otel-lgtm принимает всё это. Loki хранит логи, Tempo — трассировки, Prometheus — метрики. Поверх всего работает Grafana на localhost:3000.
Запускаете docker compose up, вызываете эндпоинт и можете увидеть конкретный запрос в виде временной шкалы. Каждый запрос EF Core отображается отдельной полосой. После этого можно сразу перейти к логам именно этого запроса.
Самое важное — такую же схему можно использовать и в продакшене, хотя я рекомендую запускать эти сервисы в отдельных контейнерах.
👉 @KodBlog
Одних логов недостаточно, чтобы понять, куда ушло время. Это был обработчик? Запрос к базе данных? Внешний вызов? В итоге приходится гадать или добавлять Stopwatch, снова разворачивать приложение и проверять ещё раз.
Именно поэтому в моём шаблоне полная картина доступна сразу.
Приложение отправляет логи, трассировки и метрики через OTLP. Один контейнер grafana/otel-lgtm принимает всё это. Loki хранит логи, Tempo — трассировки, Prometheus — метрики. Поверх всего работает Grafana на localhost:3000.
Запускаете docker compose up, вызываете эндпоинт и можете увидеть конкретный запрос в виде временной шкалы. Каждый запрос EF Core отображается отдельной полосой. После этого можно сразу перейти к логам именно этого запроса.
Самое важное — такую же схему можно использовать и в продакшене, хотя я рекомендую запускать эти сервисы в отдельных контейнерах.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🍾1
Если «результатов нет», лучше возвращать пустую коллекцию, а не null.
Если метод возвращает коллекцию, вызывающему коду почти всегда проще работать с пустой коллекцией.
Вместо:
Лучше:
Тогда вызывающий код может просто сделать так:
Никакой проверки на null перед циклом не требуется.
Одно небольшое изменение дает сразу несколько плюсов:
✔️ Чище вызывающий код
✔️ Меньше лишних проверок
✔️ Ниже риск NullReferenceException
✔️ Более понятный контракт API
В современном C# конструкция
Именно такие небольшие решения в проектировании API определяют, будет ли с ним приятно работать или разработчикам постоянно придется гадать, что метод вернет в очередной раз.
👉 @KodBlog
Если метод возвращает коллекцию, вызывающему коду почти всегда проще работать с пустой коллекцией.
Вместо:
return null;
Лучше:
return [];
Тогда вызывающий код может просто сделать так:
foreach (var user in users)
{
// ...
}
Никакой проверки на null перед циклом не требуется.
Одно небольшое изменение дает сразу несколько плюсов:
✔️ Чище вызывающий код
✔️ Меньше лишних проверок
✔️ Ниже риск NullReferenceException
✔️ Более понятный контракт API
В современном C# конструкция
[] сразу показывает намерение.Именно такие небольшие решения в проектировании API определяют, будет ли с ним приятно работать или разработчикам постоянно придется гадать, что метод вернет в очередной раз.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤2🍾1
10 навыков для .NET, которые стоит использовать в следующей разработке с ИИ.
Навык — это файл с инструкциями, который агент загружает только тогда, когда задача действительно этого требует.
1.
Проверяет код примерно на 50 типичных проблем с производительностью: async, память, строки, коллекции, LINQ, регулярные выражения, сериализация и ввод-вывод.
2.
Берёт медленный запрос и оптимизирует его так, чтобы генерировалось меньше SQL и было меньше обращений к базе данных.
3.
Проверяет то, что только что сделал агент, и ищет его «срезанные углы»: отключённые тесты, подавленные предупреждения, пустые блоки
4.
Отвечает на вопрос: «Смогли бы мои тесты поймать эту ошибку?»
5.
Интеграционные тесты с реальными базами данных, очередями и кешами, которые поднимаются в Docker, вместо моков.
6.
Интеграционные тесты с удобствами .NET Aspire: фикстуры, распределённое приложение и автоматическое обнаружение конечных точек.
7.
Читает binlog MSBuild и объясняет, почему сборка упала, когда консоль не сообщает ничего полезного.
8.
Переводит решение на Central Package Management и выравнивает версии NuGet-пакетов во всех проектах.
9.
Обновляет
10.
Декомпилирует сборку, чтобы понять, как внутри работает API фреймворка или NuGet-пакет.
Мне особенно понравился №3. Сам факт того, что существует отдельный навык для проверки «срезанных углов» агента, многое говорит о текущем состоянии разработки с ИИ.
В Claude Code они устанавливаются так:
👉 @KodBlog
Навык — это файл с инструкциями, который агент загружает только тогда, когда задача действительно этого требует.
1.
analyzing-dotnet-performanceПроверяет код примерно на 50 типичных проблем с производительностью: async, память, строки, коллекции, LINQ, регулярные выражения, сериализация и ввод-вывод.
2.
optimizing-ef-core-queriesБерёт медленный запрос и оптимизирует его так, чтобы генерировалось меньше SQL и было меньше обращений к базе данных.
3.
slopwatchПроверяет то, что только что сделал агент, и ищет его «срезанные углы»: отключённые тесты, подавленные предупреждения, пустые блоки
catch. В общем, всё, что помогает сборке пройти, не решая саму проблему.4.
test-gap-analysisОтвечает на вопрос: «Смогли бы мои тесты поймать эту ошибку?»
5.
testcontainersИнтеграционные тесты с реальными базами данных, очередями и кешами, которые поднимаются в Docker, вместо моков.
6.
aspire-integration-testingИнтеграционные тесты с удобствами .NET Aspire: фикстуры, распределённое приложение и автоматическое обнаружение конечных точек.
7.
binlog-failure-analysisЧитает binlog MSBuild и объясняет, почему сборка упала, когда консоль не сообщает ничего полезного.
8.
convert-to-cpmПереводит решение на Central Package Management и выравнивает версии NuGet-пакетов во всех проектах.
9.
migrate-dotnet9-to-dotnet10Обновляет
TargetFramework и исправляет несовместимые изменения в .NET 10, C# 14, ASP.NET Core 10 и EF Core 10.10.
ilspy-decompileДекомпилирует сборку, чтобы понять, как внутри работает API фреймворка или NuGet-пакет.
Мне особенно понравился №3. Сам факт того, что существует отдельный навык для проверки «срезанных углов» агента, многое говорит о текущем состоянии разработки с ИИ.
В Claude Code они устанавливаются так:
/plugin marketplace add dotnet/skills
/plugin marketplace add Aaronontheweb/dotnet-skills
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾2🤩1
Пора перестать использовать
И вот почему.
Я часто разбираю .NET-проекты, и эта проблема встречается почти везде.
А потом в понедельник утром начинают падать тесты, и никто не понимает почему.
Что на самом деле ломает
→ Поведение меняется между окружениями
→ Бизнес-логика начинает зависеть от часов сервера
→ Тесты проходят у тебя и падают в другом часовом поясе
→ Нельзя просто перемотать время на «следующий месяц» или «два года назад»
→ Любая логика, зависящая от времени, становится неудобной для тестирования
Как протестировать скидку, которая заканчивается в полночь?
А последний день бесплатного периода?
Или подписку, которая должна продлиться через год?
Нормально протестировать всё это можно только тогда, когда приложение получает время из источника, которым ты можешь управлять.
Решение простое — относиться ко времени как к обычной зависимости и внедрять его.
В современном .NET есть два хороших варианта.
1. Встроенный
2. Собственный интерфейс
Для новых проектов я бы использовал
Он уже входит в платформу, умеет работать с таймерами и часовыми поясами, а вместе с
Подключение через DI занимает одну строку:
После этого внедряешь его как обычный сервис и используешь
В проде поведение остаётся тем же.
А в тестах ты наконец полностью контролируешь время.
👉 @KodBlog
DateTime.Now в коде.И вот почему.
Я часто разбираю .NET-проекты, и эта проблема встречается почти везде.
DateTime.Now раскидан по сущностям домена, бизнес-логике, валидаторам и сервисам. На ревью кода на это обычно никто не обращает внимания. Выглядит как совершенно безобидный вызов.А потом в понедельник утром начинают падать тесты, и никто не понимает почему.
Что на самом деле ломает
DateTime.Now→ Поведение меняется между окружениями
→ Бизнес-логика начинает зависеть от часов сервера
→ Тесты проходят у тебя и падают в другом часовом поясе
→ Нельзя просто перемотать время на «следующий месяц» или «два года назад»
→ Любая логика, зависящая от времени, становится неудобной для тестирования
Как протестировать скидку, которая заканчивается в полночь?
А последний день бесплатного периода?
Или подписку, которая должна продлиться через год?
Нормально протестировать всё это можно только тогда, когда приложение получает время из источника, которым ты можешь управлять.
Решение простое — относиться ко времени как к обычной зависимости и внедрять его.
В современном .NET есть два хороших варианта.
1. Встроенный
TimeProvider в .NET 8 и новее2. Собственный интерфейс
IDateTimeProvider, который работает с любой версией .NETДля новых проектов я бы использовал
TimeProvider.Он уже входит в платформу, умеет работать с таймерами и часовыми поясами, а вместе с
FakeTimeProvider позволяет в тестах перемещать время куда угодно.Подключение через DI занимает одну строку:
builder.Services.AddSingleton(TimeProvider.System);
После этого внедряешь его как обычный сервис и используешь
GetUtcNow() там, где раньше был DateTime.UtcNow.В проде поведение остаётся тем же.
А в тестах ты наконец полностью контролируешь время.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🍾1👀1
Самый простой способ отправлять HTTP-запросы в .NET — использовать
Но есть интересная альтернатива.
Проблема
Для этого есть отличная библиотека Refit.
Это автоматически генерируемый и типобезопасный клиент для REST API в .NET.
Под капотом Refit всё равно использует
По сути, ты описываешь API через интерфейс, а Refit сам берёт на себя большую часть рутинной работы.
👉 @KodBlog
HttpClient.Но есть интересная альтернатива.
Проблема
HttpClient в том, что при неправильном использовании можно столкнуться с исчерпанием портов и проблемами с DNS. Плюс сериализацию и десериализацию приходится настраивать вручную.Для этого есть отличная библиотека Refit.
Это автоматически генерируемый и типобезопасный клиент для REST API в .NET.
Под капотом Refit всё равно использует
HttpClient для отправки запросов, но добавляет поверх него более удобный для разработчика слой.По сути, ты описываешь API через интерфейс, а Refit сам берёт на себя большую часть рутинной работы.
Please open Telegram to view this post
VIEW IN TELEGRAM
🤨3👍2🍾1😈1
Три главных встроенных обобщённых делегата в C# — Func, Action и Predicate.
Делегаты можно воспринимать как ссылки на функции. Они используются для передачи поведения, обратных вызовов и взаимодействия между разными частями программы.
В C# есть три основных встроенных обобщённых делегата.
1️⃣ Func
Принимает значения и возвращает результат.
Например:
Func<int, string>
Здесь на вход передаётся int, а возвращается string.
2️⃣ Action
Принимает значения, но ничего не возвращает.
Например:
Action<string>
Такой делегат получает строку и выполняет какое-то действие без возвращаемого значения.
3️⃣ Predicate
Принимает значение и всегда возвращает bool.
Например:
Predicate<Student>
Он получает объект Student и проверяет некоторое условие, возвращая true или false.
Эти делегаты очень широко используются внутри .NET и позволяют не создавать собственный тип делегата каждый раз.
Простой пример.
Создаём класс Student с несколькими свойствами, затем список студентов и добавляем в него данные.
После этого можно увидеть, как разные методы работают с разными типами делегатов.
Select принимает Func.
ForEach принимает Action.
FindAll принимает Predicate.
По сути, Func используется, когда нужен результат, Action — когда нужно просто выполнить действие, а Predicate — когда нужно проверить условие и получить true или false.
👉 @KodBlog
Делегаты можно воспринимать как ссылки на функции. Они используются для передачи поведения, обратных вызовов и взаимодействия между разными частями программы.
В C# есть три основных встроенных обобщённых делегата.
1️⃣ Func
Принимает значения и возвращает результат.
Например:
Func<int, string>
Здесь на вход передаётся int, а возвращается string.
2️⃣ Action
Принимает значения, но ничего не возвращает.
Например:
Action<string>
Такой делегат получает строку и выполняет какое-то действие без возвращаемого значения.
3️⃣ Predicate
Принимает значение и всегда возвращает bool.
Например:
Predicate<Student>
Он получает объект Student и проверяет некоторое условие, возвращая true или false.
Эти делегаты очень широко используются внутри .NET и позволяют не создавать собственный тип делегата каждый раз.
Простой пример.
Создаём класс Student с несколькими свойствами, затем список студентов и добавляем в него данные.
После этого можно увидеть, как разные методы работают с разными типами делегатов.
Select принимает Func.
ForEach принимает Action.
FindAll принимает Predicate.
По сути, Func используется, когда нужен результат, Action — когда нужно просто выполнить действие, а Predicate — когда нужно проверить условие и получить true или false.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2❤1🍾1
10 MCP-серверов, которые стоит рассмотреть для следующего .NET-проекта с ИИ.
MCP-сервер даёт агенту инструмент, который позволяет выйти за пределы чата и работать с реальными системами — читать данные, запускать действия и взаимодействовать с инфраструктурой.
1. Microsoft Learn
Официальная актуальная документация по C#, ASP.NET Core, EF Core и NuGet.
2. Context7
Похожий вариант, но уже для библиотек, которые не относятся к Microsoft.
3. NuGet MCP Server
Позволяет агенту искать пакеты, управлять зависимостями и работать с NuGet.
4. Binlog MCP Server
Даёт структурированный доступ к ошибкам, предупреждениям, целям и свойствам из журналов сборки MSBuild.
5. SQL MCP Server
Работа со схемами и CRUD-операциями в локальном SQL Server, Azure SQL или Fabric.
6. Azure MCP
Даёт агенту доступ к вашим ресурсам Azure.
7. Azure DevOps MCP
Работа с задачами, запросами на слияние, конвейерами, планами тестирования и вики.
8. Playwright MCP
Позволяет запускать сквозные тесты вашего веб-приложения.
9. GitHub MCP
Работа с задачами, запросами на слияние и GitHub Actions.
10. MCP SDK для C#
Это уже не готовый сервер. С его помощью можно написать собственный MCP-сервер и открыть агенту доступ к своей существующей системе.
По сути, MCP превращает ИИ из обычного собеседника в инструмент, который реально может взаимодействовать с вашим .NET-проектом и окружающей его инфраструктурой.
👉 @KodBlog
MCP-сервер даёт агенту инструмент, который позволяет выйти за пределы чата и работать с реальными системами — читать данные, запускать действия и взаимодействовать с инфраструктурой.
1. Microsoft Learn
Официальная актуальная документация по C#, ASP.NET Core, EF Core и NuGet.
2. Context7
Похожий вариант, но уже для библиотек, которые не относятся к Microsoft.
3. NuGet MCP Server
Позволяет агенту искать пакеты, управлять зависимостями и работать с NuGet.
4. Binlog MCP Server
Даёт структурированный доступ к ошибкам, предупреждениям, целям и свойствам из журналов сборки MSBuild.
5. SQL MCP Server
Работа со схемами и CRUD-операциями в локальном SQL Server, Azure SQL или Fabric.
6. Azure MCP
Даёт агенту доступ к вашим ресурсам Azure.
7. Azure DevOps MCP
Работа с задачами, запросами на слияние, конвейерами, планами тестирования и вики.
8. Playwright MCP
Позволяет запускать сквозные тесты вашего веб-приложения.
9. GitHub MCP
Работа с задачами, запросами на слияние и GitHub Actions.
10. MCP SDK для C#
Это уже не готовый сервер. С его помощью можно написать собственный MCP-сервер и открыть агенту доступ к своей существующей системе.
По сути, MCP превращает ИИ из обычного собеседника в инструмент, который реально может взаимодействовать с вашим .NET-проектом и окружающей его инфраструктурой.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤3🍾2
params существует в C# ещё с версии 1.0, но большинство разработчиков сегодня знают только половину того, что он умеет.params позволяет методу принимать переменное количество аргументов без необходимости вручную создавать массив на стороне вызывающего кода.static void PrintAll(params object[] values)
{
foreach (object value in values)
{
Console.WriteLine(value);
}
}
Один и тот же метод можно вызвать с нулём, одним или несколькими аргументами:
PrintAll();
PrintAll("Hello");
PrintAll("Hello", 42, true);
До C# 13 параметр
params должен был быть одномерным массивом.C# 13 снимает это ограничение. Теперь
params можно использовать с любым поддерживаемым типом коллекции, включая:✔️
Span<T>✔️
ReadOnlySpan<T>✔️ Классы и структуры, реализующие
IEnumerable<T>, у которых есть доступный конструктор без параметров и подходящий экземплярный метод Add✔️ Типы, настроенные через метод построения коллекции
✔️
IEnumerable<T>✔️
IReadOnlyCollection<T>✔️
IReadOnlyList<T>✔️
ICollection<T>✔️
IList<T>Например:
public static void PrintAll<T>(
params ReadOnlySpan<T> items)
{
for (int i = 0; i < items.Length; i++)
{
Console.Write(items[i]);
Console.Write(' ');
}
Console.WriteLine();
}
Вызывается он так же, как обычный
params с массивом:PrintAll("C#", "13", "works");
PrintAll(10, 20, 30, 40);Когда используется интерфейс вроде
IEnumerable<T> или IList<T>, компилятор сам создаёт подходящее хранилище для переданных аргументов.Коллекции параметров на основе
Span также дают компилятору больше возможностей для оптимизации. Во многих вызовах с развёрнутым списком аргументов он может использовать временное хранилище в стеке и избежать временного выделения памяти в куче, которое обычно требуется для массива params.Это не означает, что любой метод с
Span<T> автоматически работает без аллокаций. Но теперь больше нет требования, чтобы каждый вызов params с отдельными аргументами обязательно создавал массив в куче.То же удобство вызова, которое было у нас ещё со времён C# 1.0.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍2🔥1🍾1
now() — это не «сейчас», а скорее «когда-то было сейчас».На самом деле
now() возвращает время начала текущей транзакции. Реальные часы продолжают идти, но каждый последующий вызов now(), CURRENT_TIMESTAMP, CURRENT_TIME и CURRENT_DATE внутри этой же транзакции всё равно возвращает одно и то же время.В Postgres это называется transaction-frozen timestamp.
То есть
INSERT на 10 000 строк с created_at DEFAULT now() получит один и тот же timestamp для всех строк, а не 10 000 слегка отличающихся значений.Три варианта времени:
•
now() — традиционный для Postgres вариант, хотя он есть и в других СУБД, но это не стандарт SQL. В стандарте SQL используется CURRENT_TIMESTAMP. В Postgres также есть transaction_timestamp(), который работает так же, как now(), но хотя бы честно говорит об этом своим названием.•
statement_timestamp() обновляется один раз на каждый SQL-запрос. Это полезно внутри длинной транзакции, когда вам нужно фиксировать время выполнения отдельных команд, но не переходить к реальному системному времени.•
clock_timestamp() — единственный timestamptz, который меняется даже во время выполнения одного SQL-запроса.Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🍾2👏1
Похоже, для создания презентаций появился настоящий чит-код: загружаете документ и получаете готовый PPTX, где каждую страницу можно нормально редактировать.
На GitHub проект уже набрал 50 тысяч звёзд.
Раньше больше всего бесило, что ИИ для презентаций часто выдавал набор картинок или статичный шаблон. Захотели передвинуть блок или поменять размер шрифта — приходится переделывать вручную.
PPT Master создаёт нативные объекты PowerPoint. Фигуры, соединительные линии, диаграммы, таблицы, мастер-слайды и макеты остаются настоящими редактируемыми элементами.
Диаграммы и таблицы по умолчанию экспортируются в редактируемом DrawingML, а формулы — в OMML, который можно редактировать начиная с PowerPoint 2010. Если клиент попросил поменять данные, всю презентацию заново генерировать не придётся.
Работает примерно так.
Берёте исследовательский отчёт в PDF или DOCX, загружаете его, а система читает документ целиком и собирает из него PPTX. Можно добавить переходы между слайдами, анимации объектов, заметки докладчика и даже озвучку в заметках.
Если у компании уже есть фирменный шаблон, PPT Master может взять оформление из существующего PPTX. Можно и не переделывать всю презентацию, а перегенерировать только отдельные страницы.
Есть два режима. Полная генерация занимает больше времени, а быстрая генерация одной страницы необратима и подходит, когда нужно сделать всё максимально быстро.
Кроме взаимодействия с ИИ-моделью, всё остальное работает локально.
Потому что на самом деле при подготовке отчётов больше всего времени обычно уходит не на придумывание содержания, а на то, чтобы нормально разложить его по слайдам.
GitHub:
https://github.com/hugohe3/ppt-master
👉 @KodBlog
На GitHub проект уже набрал 50 тысяч звёзд.
Раньше больше всего бесило, что ИИ для презентаций часто выдавал набор картинок или статичный шаблон. Захотели передвинуть блок или поменять размер шрифта — приходится переделывать вручную.
PPT Master создаёт нативные объекты PowerPoint. Фигуры, соединительные линии, диаграммы, таблицы, мастер-слайды и макеты остаются настоящими редактируемыми элементами.
Диаграммы и таблицы по умолчанию экспортируются в редактируемом DrawingML, а формулы — в OMML, который можно редактировать начиная с PowerPoint 2010. Если клиент попросил поменять данные, всю презентацию заново генерировать не придётся.
Работает примерно так.
Берёте исследовательский отчёт в PDF или DOCX, загружаете его, а система читает документ целиком и собирает из него PPTX. Можно добавить переходы между слайдами, анимации объектов, заметки докладчика и даже озвучку в заметках.
Если у компании уже есть фирменный шаблон, PPT Master может взять оформление из существующего PPTX. Можно и не переделывать всю презентацию, а перегенерировать только отдельные страницы.
Есть два режима. Полная генерация занимает больше времени, а быстрая генерация одной страницы необратима и подходит, когда нужно сделать всё максимально быстро.
Кроме взаимодействия с ИИ-моделью, всё остальное работает локально.
Потому что на самом деле при подготовке отчётов больше всего времени обычно уходит не на придумывание содержания, а на то, чтобы нормально разложить его по слайдам.
GitHub:
https://github.com/hugohe3/ppt-master
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
GitHub - hugohe3/ppt-master: AI turns documents or topics into real, native PowerPoint decks—with native shapes, transitions and…
AI turns documents or topics into real, native PowerPoint decks—with native shapes, transitions and animations, data-backed charts and tables on demand, audio narration from speaker notes, and supp...
👍3🔥1🌭1🍾1
Добавляем Fixed Window Rate Limiter в ASP.NET Core
Можно настроить:
Нужно ли ставить входящие запросы в очередь
Rate limiting работает только in-memory.
Если нужен distributed rate limiter, часто используют что-то вроде Redis.
А для долгоживущих и персистентных лимитов можно использовать даже Postgres с locking, чтобы гарантировать соблюдение ограничений.
👉 @KodBlog
Можно настроить:
PermitLimit — количество разрешённых запросовWindow — размер временного окна в секундах (TimeSpan)Нужно ли ставить входящие запросы в очередь
Rate limiting работает только in-memory.
Если нужен distributed rate limiter, часто используют что-то вроде Redis.
А для долгоживущих и персистентных лимитов можно использовать даже Postgres с locking, чтобы гарантировать соблюдение ограничений.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4🔥1🍾1
Что такое Domain Event в DDD?
Aggregates выступают в роли границы согласованности (consistency boundary) в домене. И в какой-то момент неизбежно возникает необходимость организовать взаимодействие между двумя aggregates.
Сделать это можно с использованием eventual consistency и domain events. Один aggregate создаёт domain event, а другие aggregates могут подписаться на это событие и соответствующим образом его обработать.
Вот как это можно реализовать с помощью EF Core:
https://milanjovanovic.tech/blog/how-to-use-domain-events-to-build-loosely-coupled-systems
👉 @KodBlog
Aggregates выступают в роли границы согласованности (consistency boundary) в домене. И в какой-то момент неизбежно возникает необходимость организовать взаимодействие между двумя aggregates.
Сделать это можно с использованием eventual consistency и domain events. Один aggregate создаёт domain event, а другие aggregates могут подписаться на это событие и соответствующим образом его обработать.
Вот как это можно реализовать с помощью EF Core:
https://milanjovanovic.tech/blog/how-to-use-domain-events-to-build-loosely-coupled-systems
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🍾1
от как можно реализовать tenant-based query filter с помощью EF Core.
Понадобится сервис, который будет предоставлять
Получить это значение можно из request header или из JWT (cookie) claim.
Побочный эффект такого подхода: использовать
👉 @KodBlog
Понадобится сервис, который будет предоставлять
TenantId для текущего tenant.Получить это значение можно из request header или из JWT (cookie) claim.
Побочный эффект такого подхода: использовать
DbContext получится только в рамках HTTP request.Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🍾1
Моя любимая фича в C# 12 — Collection Expressions.
Она упрощает создание распространённых типов коллекций. С помощью spread-оператора
Collection Expressions дают единый способ создания новых коллекций. Небольшое изменение, но теперь именно этот вариант используется по умолчанию практически во всём C#-коде.
👉 @KodBlog
Она упрощает создание распространённых типов коллекций. С помощью spread-оператора
.. можно даже встроить существующие коллекции прямо в новую.Collection Expressions дают единый способ создания новых коллекций. Небольшое изменение, но теперь именно этот вариант используется по умолчанию практически во всём C#-коде.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8🥴2🍾1
This media is not supported in your browser
VIEW IN TELEGRAM
Браузерная игрушка обучает C#
RPG, где прогресс зависит не от кликов, а от того, насколько хорошо ты пишешь код на C#
Что внутри:
Отличный способ учиться C# в формате приключения. Игра затягивает, а навыки прокачиваются сами собой
https://rpg.dijix.com.ua/
👉 @KodBlog
RPG, где прогресс зависит не от кликов, а от того, насколько хорошо ты пишешь код на C#
Что внутри:
🔄 Вы становитесь героем фантастического мира рыцари, монстры, нелегкие испытания🔄 Но вместо обычных “нажми кнопку, чтобы победить” вам нужно писать код на C#, чтобы решать задачи и прокачивать персонажа🔄 Стратегия, логика и программирование объединены развиваете не только персонажа, но и себя как разработчика
Отличный способ учиться C# в формате приключения. Игра затягивает, а навыки прокачиваются сами собой
https://rpg.dijix.com.ua/
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2🥴2🍾1