Forwarded from Just Xor
Generic Repository это антипаттерн. Не существует определенных правил каким должен быть интерфейс репозитория - это всецело зависит от предметной области.
Однако есть класс простых приложений, которые работают с данными одинаково. И когда нужно получить простой универсальный способ работы с данными - это единственный случай, когда использование обобщенного репозитория оправдано.
▪Читать подробно
@csharp_1001_notes
Please open Telegram to view this post
VIEW IN TELEGRAM
Обработчики исключений с пользовательской фильтрацией в C# ⬇
Они позволяют нам добавлять условия в блоки catch, чтобы исключения не выводились только на основе типа исключения.
Я использую их лишь изредка, но предпочитаю их операторам if/else внутри блока catch.
@csharp_1001_notes
Они позволяют нам добавлять условия в блоки catch, чтобы исключения не выводились только на основе типа исключения.
Я использую их лишь изредка, но предпочитаю их операторам if/else внутри блока catch.
@csharp_1001_notes
Блог о переходе Microsoft Office с RTC (Real-Time Channel) на современный .
NET
! Это было одно из самых первых применений
SignalR
в компании!#dotnet #aspnetcore #signalr
https://devblogs.microsoft.com/dotnet/office-rtc-dotnet-migration/
@csharp_1001_notes
Please open Telegram to view this post
VIEW IN TELEGRAM
C помощью делегирующих обработчиков можно решить множество проблем:
- Протоколирование
- Трассировка
- Валидация
- Аутентификация
- Авторизация
https://dotnet.microsoft.com/en-us/apps/aspnet
@csharp_1001_notes
Please open Telegram to view this post
VIEW IN TELEGRAM
Простой способ для генерации классов C# из данных JSON/XML! 🤖🔥
В Visual Studio:
1/ Скопируйте содержимое
2/ В Visual Studio нажмите на Edit -> Paste Special -> Paste JSON as classes (или XML).
3/ Вот и все!
@csharp_1001_notes
В Visual Studio:
1/ Скопируйте содержимое
JSON/XM
L.2/ В Visual Studio нажмите на Edit -> Paste Special -> Paste JSON as classes (или XML).
3/ Вот и все!
@csharp_1001_notes
.NET
, который собирает данные Active Directory
по протоколу Active Directory Web Services (ADWS)
.SOAPHound является альтернативой ряду инструментов безопасности с открытым исходным кодом, которые обычно используются для извлечения данных Active Directory через протокол LDAP.
SOAPHound способен извлекать ту же информацию без прямого взаимодействия с сервером LDAP.
Вместо этого LDAP-запросы оборачиваются в серию SOAP-сообщений, которые отправляются на сервер ADWS с помощью канала связи NET TCP Binding.
Затем сервер ADWS разворачивает LDAP-запросы и направляет их на LDAP-сервер, работающий на том же контроллере домена.
В результате LDAP-трафик не может быть обнаружен обычными средствами мониторинга.
• Github
@csharp_1001_notes
Please open Telegram to view this post
VIEW IN TELEGRAM
В области веб-разработки Blazor WebAssembly является революционным решением.
Он позволяет разработчикам создавать интерактивные веб-приложения на стороне клиента, используя
.NET и C#, а не JavaScript.
Это не только открывает новые возможности для веб-разработки, но и приводит к появлению новых методов размещения и развертывания этих приложений.
https://www.thetechplatform.com/post/different-methods-to-host-and-deploy-blazor-webassembly
@csharp_1001_notes
Please open Telegram to view this post
VIEW IN TELEGRAM
⚡️ CI/CD Workflow: упрощенный гайд от ByteByteGo
CI/CD — это методология, которая позволяет автоматизировать процесс разработки и доставки ПО в продакшн.
Будь вы разработчиком, специалистом по DevOps, тестировщиком или занимаетесь любой современной ролью в ИТ, CI/CD пайплайны стали неотъемлемой частью процесса разработки.
@csharp_1001_notes
CI/CD — это методология, которая позволяет автоматизировать процесс разработки и доставки ПО в продакшн.
Будь вы разработчиком, специалистом по DevOps, тестировщиком или занимаетесь любой современной ролью в ИТ, CI/CD пайплайны стали неотъемлемой частью процесса разработки.
@csharp_1001_notes
Please open Telegram to view this post
VIEW IN TELEGRAM
Перехватчики в EF Core помогают перехватывать, изменять или подавлять операции EF Core.
Перехватчики регистрируются для каждого экземпляра DbContext при настройке контекста. Каждый перехватчик реализует интерфейс IInterceptor. Несколько распространённых производных интерфейсов включают
- IDbCommandInterceptor,
- IDbConnectionInterceptor,
- IDbTransactionInterceptor,
- ISaveChangesInterceptor.
Вам не нкжно реализовывать эти интерфейсы напрямую.
Лучше использовать конкретные реализации и переопределить необходимые методы.
Вот вариант использования перехватчиков с помощью самого распространённого перехватчика
SaveChangesInterceptor
, который добавляет поведение при сохранении изменений в базе данных.Добавление записей аудита
Записи аудита изменений сущностей - ценная функция в некоторых приложениях. Вы записываете дополнительную информацию аудита каждый раз, когда объект создаётся или изменяется. Также это могут быть значения «до» и «после», в зависимости от ваших требований.
Например, создадим интерфейс IAuditable с датами создания и изменения объекта:
public interface IAuditable
{
DateTime Created { get; }
DateTime? Modified { get; }
}
Добавим UpdateInterceptor для записи значений аудита. Он использует ChangeTracker для поиска всех экземпляров IAuditable и устанавливает соответствующее значение свойства. Здесь мы используем метод SavingChangesAsync, который запускается до того, как изменения будут сохранены в БД.
internal sealed class UpdateInterceptor
: SaveChangesInterceptor
{
public override
ValueTask<InterceptionResult<int>>
SavingChangesAsync(
DbContextEventData e,
InterceptionResult<int> result,
CancellationToken ct = default)
{
if (e.Context is not null)
UpdateEntities(e.Context);
return base
.SavingChangesAsync(e, result, ct);
}
private static void
UpdateEntities(DbContext ctx)
{
var now = DateTime.UtcNow;
var entities = ctx
.ChangeTracker
.Entries<IAuditable>()
.ToList();
foreach (var e in entities)
{
if (e.State == EntityState.Added)
e.Property(
nameof(IAuditable.Created)) = now;
if (e.State == EntityState.Modified)
e.Property(
nameof(IAuditable.Modified)) = now;
}
}
}
Эту реализацию можно легко расширить, включив в неё, например, информацию о текущем пользователе.
Зарегистрировать перехватчик можно следующим образом:
services.AddSingleton<UpdateInterceptor>();
services.AddDbContext<
IApplicationDbContext,
AppDbContext>(
(sp, opts) => opts
.UseSqlServer(connString)
.AddInterceptors(
sp.GetRequiredService<UpdateInterceptor>());
👉 Подробнее
@csharp_1001_notes
Please open Telegram to view this post
VIEW IN TELEGRAM
Эта статья знакомит с концепцией отказоустойчивости и хаос-инженерии в приложениях .NET с использованием библиотеки Polly и рассказывает о новых возможностях, позволяющих использовать хаос-инженерию.
В ней приведено практическое руководство по интеграции стратегий хаоса в HTTP-клиенты и показывается, как настраивать конвейеры отказоустойчивости для повышения эффективности работы вашего приложения.
▪Статья
▪Polly
@csharp_1001_notes
Please open Telegram to view this post
VIEW IN TELEGRAM
Шаблон Хранитель используется, когда:
▪необходимо сохранить снимок состояния объекта (или его части) для последующего восстановления
▪прямой интерфейс получения состояния объекта раскрывает детали реализации и нарушает инкапсуляцию объекта
В C# паттерн Memento может быть реализован с помощью комбинации трех классов:
Originator, Memento и Caretaker.
▪ Подробнее
@csharp_1001_notes
Please open Telegram to view this post
VIEW IN TELEGRAM
EF 8 генерирует бодее эффективные запросы, используя
Разницу в запросах вы можете увидеть в примере на картинке.
@csharp_1001_notes
IN
вместо EXISTS
, когда метод Contains
используется с подзапросом.Разницу в запросах вы можете увидеть в примере на картинке.
@csharp_1001_notes
▪Часть 1
▪Часть2
@csharp_1001_notes
Please open Telegram to view this post
VIEW IN TELEGRAM
System.IO.Hashing - это действительно полезный пакет
📌Узнать о нем подробнее
@csharp_1001_notes
NuGet
для некриптографического хэширования в .NET
.📌Узнать о нем подробнее
@csharp_1001_notes
⚡️ AspNetCore.ApiGateway
Представляем крутой инструмент: микросервис с конвейером запросов #ASPNETCore.
Без проблем перейдите от веб-интерфейса #ASPNETCore к Veritas API Gateway, в который входят, Swagger, методы авторизации, фильтры, балансировщик нагрузки и многое другое.
▪ Github
@csharp_1001_notes
Представляем крутой инструмент: микросервис с конвейером запросов #ASPNETCore.
Без проблем перейдите от веб-интерфейса #ASPNETCore к Veritas API Gateway, в который входят, Swagger, методы авторизации, фильтры, балансировщик нагрузки и многое другое.
▪ Github
@csharp_1001_notes
⚡️ Параллельная Публикация Уведомлений в MediatR
MediatR — это популярная библиотека с простой реализацией паттерна посредник в .NET.
С ростом популярности паттерна
Издатель — подписчик — поведенческий шаблон проектирования передачи сообщений, в котором отправители сообщений, именуемые издателями (англ. publishers), напрямую не привязаны программным кодом отправки сообщений к подписчикам (англ. subscribers).
Но она также поддерживает паттерн издатель-подписчик с использованием уведомлений. Можно опубликовать экземпляр INotification, и несколько подписчиков обработают опубликованное сообщение.
Разберемся как это можно делать параллельно.
Нам нужен класс, реализующий INotification:
Реализация по умолчанию - ForeachAwaitPublisher:
Но вы также можете использовать TaskWhenAllPublisher (показаны только отличия в реализации метода Publish:
Настройка стратегии публикации происходит в методе AddMediatR.
Если вы хотите использовать стратегию TaskWhenAllPublisher, вы можете:
- указать значение для свойства NotificationPublisher (тогда издатель будет синглтоном),
- указать тип стратегии в свойстве NotificationPublisherType и использовать свойство ServiceLifetime для задания времени жизни:
Плюсы
Параллельного запуска обработчиков уведомлений обеспечивает значительное повышение производительности по сравнению с поведением по умолчанию.
Однако обратите внимание, что все обработчики будут использовать одну и ту же область видимости. Если у вас есть экземпляры сервисов, которые не поддерживают конкурентный доступ, вы можете столкнуться с проблемами. К сожалению, одним из таких является EF Core DbContext.
📌 Подробнее
@csharp_1001_notes
MediatR — это популярная библиотека с простой реализацией паттерна посредник в .NET.
Посредник
— паттерн шаблон проектирования, обеспечивающий взаимодействие множества объектов, формируя при этом слабое зацепление и избавляя объекты от необходимости явно ссылаться друг на друга.С ростом популярности паттерна
CQRS MediatR
стала популярной библиотекой для реализации команд и запросов.Издатель — подписчик — поведенческий шаблон проектирования передачи сообщений, в котором отправители сообщений, именуемые издателями (англ. publishers), напрямую не привязаны программным кодом отправки сообщений к подписчикам (англ. subscribers).
Но она также поддерживает паттерн издатель-подписчик с использованием уведомлений. Можно опубликовать экземпляр INotification, и несколько подписчиков обработают опубликованное сообщение.
Разберемся как это можно делать параллельно.
Нам нужен класс, реализующий INotification:
public record OrderCreated(Guid OrderId) : INotification;
А также реализация соответствующего INotificationHandler:
public class OrderCreatedHandler :
INotificationHandler<OrderCreated>
{
private readonly INotificationService svc;
public OrderCreatedHandler(
INotificationService service)
{
svc = service;
}
public async Task Handle(
OrderCreated notification,
CancellationToken ct)
{
await svc.SendOrderCreatedEmail(
notification.OrderId,
ct);
}
}
Теперь можно публиковать сообщение с помощью IMediator или IPublisher:
await publisher.Publish(
new OrderCreated(order.Id),
cancellationToken);
MediatR вызовет все соответствующие обработчики. До 12й версии MediatR стратегия публикации вызывала каждый обработчик по отдельности. Однако появился новый интерфейс INotificationPublisher, управляющий тем, как вызываются обработчики.
Реализация по умолчанию - ForeachAwaitPublisher:
public class ForeachAwaitPublisher
: INotificationPublisher
{
public async Task Publish(
IEnumerable<NotificationHandlerExecutor> executors,
INotification notification,
CancellationToken ct)
{
foreach (var e in executors)
{
await e
.HandlerCallback(notification, ct)
.ConfigureAwait(false);
}
}
}
Она вызывает обработчики по одному и завершается неудачей при ошибке в одном из обработчиков.
Но вы также можете использовать TaskWhenAllPublisher (показаны только отличия в реализации метода Publish:
var tasks = executors
.Select(e =>
e.HandlerCallback(notification, ct))
.ToArray();
return Task.WhenAll(tasks);
TaskWhenAllPublisher вызывает все обработчики одновременно и выполняет их все независимо от того, возникали ли в них ошибки. Если вы сохраните задачу, возвращенную TaskWhenAllPublisher, вы можете получить доступ к свойству Task.Exception, содержащему экземпляр AggregateException, и реализовать обработку исключений.
Настройка стратегии публикации происходит в методе AddMediatR.
Если вы хотите использовать стратегию TaskWhenAllPublisher, вы можете:
- указать значение для свойства NotificationPublisher (тогда издатель будет синглтоном),
- указать тип стратегии в свойстве NotificationPublisherType и использовать свойство ServiceLifetime для задания времени жизни:
services.AddMediatR(cfg => {
…
cfg.NotificationPublisher =
new TaskWhenAllPublisher();
// или
cfg.NotificationPublisherType =
typeof(TaskWhenAllPublisher);
cfg.ServiceLifetime = ServiceLifetime.Transient;
});
Вы также можете реализовать пользовательский экземпляр INotificationPublisher и вместо этого использовать собственную реализацию.
Плюсы
Параллельного запуска обработчиков уведомлений обеспечивает значительное повышение производительности по сравнению с поведением по умолчанию.
Однако обратите внимание, что все обработчики будут использовать одну и ту же область видимости. Если у вас есть экземпляры сервисов, которые не поддерживают конкурентный доступ, вы можете столкнуться с проблемами. К сожалению, одним из таких является EF Core DbContext.
📌 Подробнее
@csharp_1001_notes
⚡️ Каждый разработчик должен знать о тестовых контейнерах. Это отличный инструмент, который нужно знать и применять, когда он вам понадобится.
Вот пример работы с Testcontainersна .NET:
https://testcontainers.com/guides/getting-started-with-testcontainers-for-dotnet/
#dotnet #csharp #fsharp
@csharp_1001_notes
Вот пример работы с Testcontainersна .NET:
https://testcontainers.com/guides/getting-started-with-testcontainers-for-dotnet/
#dotnet #csharp #fsharp
@csharp_1001_notes
🚀 Text2sql
Нейросеть, специализирующаяся на написании SQL-запросов (и не только) по текстовому описанию
Описание:
Ответ нейросети:
🔗 text2sql.ai
@csharp_1001_notes
Нейросеть, специализирующаяся на написании SQL-запросов (и не только) по текстовому описанию
Описание:
A Regex expression to match a password that contains at least one lowercase letter, one uppercase letter, one digit, one special character, and is at least 8 characters long
Ответ нейросети:
^(?=.*d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()_+}{":;'/?.><,])(?=.*[^s]).{8,}$
🔗 text2sql.ai
@csharp_1001_notes
aspire dashboard
, работающим как автономный контейнер.https://learn.microsoft.com/en-us/samples/dotnet/aspire-samples/aspire-standalone-dashboard/
@csharp_1001_notes
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: реализуй на C# метод расширения для строки, который будет проверять, является ли данная строка палиндромом.
Палиндром — это слово/фраза/последовательность символов, которая читается одинаково в обе стороны ("шалаш", "ротор", "12321")
Получилось?
Можешь смотреть код возможного решения
#junior
@csharp_1001_notes
Please open Telegram to view this post
VIEW IN TELEGRAM