Уютное сообщество C# разработчиков
2.52K subscribers
44 photos
53 links
Уютное сообщество C# - обучающий канал для разработчиков.

Полезные материалы по языку программирования.
Тесты на знание C#
Подсказки и трюки языка

@aldrson @viktorreh
加入频道
Многоликая регистрация в стандартном контейнере

Допустим, у нас есть некоторый класс, который реализует более одного интерфейса:

public interface IBar {}
public interface IFoo {}

public class FooBar : IFoo, IBar {}


Наша задача зарегистировать экземпляр FooBar таким образом, чтобы при внедрении зависимостей IBar и IFoo использовался один и тот же объект.

Попытавшись совершить регистрацию наивным путём, мы потерпим неудачу, зависимости будут ссылаться на разные экземпляры FooBar:

services.AddSingleton<IFoo, FooBar>();
services.AddSingleton<IBar, FooBar>();


Но проблема вполне решаема, достаточно лишь зарегистрировать вначале экземпляр FooBar и затем ссылаться на него:

services.AddSingleton<FooBar>();
services.AddSingleton<IFoo>(x => x.GetRequiredService<FooBar>());
services.AddSingleton<IBar>(x => x.GetRequiredService<FooBar>());

#полезное #tips
👍31
Пусть объявлен кортеж: var tuple = (5, 10). Как обратиться к значению 5?
Anonymous Quiz
30%
tuple[0]
56%
tuple.Item1
8%
tuple.first
5%
tuple.5
😁3
Autofac. Именованные сервисы

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

Например, у нас есть сервис IDisplay, отображающий какие-то произведения искусства IArtwork.
Чтобы указать, что мы хотим внедрить конкретную реализацию MyPainting, можно использовать атрибут KeyFilterAttribute.
По указанному ключу, он проведёт фильтрацию и выберет нужную зависимость.

Пример:


public class ArtDisplay : IDisplay
{
public ArtDisplay([KeyFilter("MyPainting")] IArtwork art) { ... }
}

// ...

var builder = new ContainerBuilder();

builder.RegisterType<MyPainting>().Keyed<IArtwork>("MyPainting");
builder.RegisterType<ArtDisplay>().As<IDisplay>().WithAttributeFiltering();

// ...
var container = builder.Build();

#полезное #tips
4👍2🤔2❤‍🔥1
Знали ли вы...

Что в .NET 7 при разработке API больше не требуется явно указывать атрибут [FromServices] для зависимостей, указанных в параметре метода?

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

Соответственно, такой код спокойно отработает без ошибок:

Services.AddScoped<SomeCustomType>();

[Route("[controller]")]
[ApiController]
public class MyController : ControllerBase
{
public ActionResult Get(SomeCustomType service) => Ok();
}

Ну а в случае, когда такое неявное поведение не нравится или не требуется, его можно отключить следующим образом:

Services.Configure<ApiBehaviorOptions>(options =>
{
options.DisableImplicitFromServicesParameters = true;
})

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

#полезное #tips
👍13😨2
Какой тип данных используется для хранения символов?
Anonymous Quiz
9%
string
89%
char
2%
byte
1%
short
🥴18🥱6😁3💩3👍2👎2🤯2🦄2🐳1🗿1
Как изменить таймаут для конкретного запроса в HttpClient?

Одной из лучших практик по работе с HttpClient в C# считается переиспользование одного экземпляра клиента для множества запросов. Как минимум во избежание port exhaustion.

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

Проблема в том, что HttpClient.Timeout устанавливается единожды, во время создания клиента. И несмотря на наличие public set'тера, это значение не может быть изменено впоследствии. Любые попытки пресекаются выбрасыванием InvalidOperationException.

Но я бы не писал этот пост, если бы не существовало решения проблемы. А решение довольно простое:
TimeSpan timeout = GetMyTimeout();
using (var tokenSource = new CancellationTokenSource(timeout))
{
var response = await httpClient.GetAsync(uri, tokenSource.Token);
HandleResponse(response);
}


Такое решение можно не только использовать "в лоб", но и обернуть в пайплайн из DelegatingHandler'ов. Для того чтобы оно работало, потребуется убедиться в двух вещах:

1️⃣ Пользовательский таймаут меньше того, что установлен в HttpClient.Timeout

2️⃣ Пользовательский таймаут валиден. Проще говоря, время ожидания больше 0 секунд.

#полезное #tips
9👍4
Какая технология используется для работы с базами данных в C#?
Anonymous Quiz
3%
JDBC
9%
ODBC
5%
DBI
marker interface

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

Также, маркерный интерфейс может быть необходимым злом при отсутствии поддержки в языке discriminated union types.
К сожалению, в объектно-ориентированных языках вроде C# объявить тип, который будет чем-то конкретным из указанного набора, невозможно.

Поэтому, приходится прибегать к таким уловкам.

Почему маркерных интерфейсов стоит избегать?
Главная проблема такого подхода - нарушение инкапсуляции.

Объект сам по себе теперь обладает неявным контролем над возможностями внешнего использования. Более того, он знает окружение, в котором будет использоваться.

Применение маркерного интерфейса подразумевает, что где-то будет находится проверка на этот маркер. Это противоречит идее инкапсуляции, потому что у объекта появляется знание о реализации той части системы, которая находится совершенно вне зоны его «полномочий».

В общем, обычный интерфейс говорит окружающему миру о том как он может быть использован, пустой, маркерный, о том, как должен быть использован.

#полезное #tips
👍4
Какой класс используется для создания нового потока в C#?
Anonymous Quiz
79%
System.Threading.Thread
12%
System.Threading.Tasks.Task
6%
System.Threading.ThreadPool
2%
System.Threading.Tasks.Parallel
🥴6
На пальцах про AAA

Как вы могли понять речь пойдёт не о батарейках или играх. Сегодняшний пост про юнит-тестирование.

Согласитесь, в таком сложном мире как программирование сложно ориентироваться, когда всё лежит где попало, не на своих местах.

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

Arrange

В этой секции находится код, ответственный за настройку теста. Создание объектов, подготовка данных, настройка моков и так далее.

Act

Затем идёт действие. То есть, непосредственно вызов тестируемого функционала.

Assert

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

Вот и получается, что паттерн Arrange-Act-Assert за счёт своей простоты и эффективности в отношении организации и написания тестов стал де-факто стандартом индустрии.

#полезное #tips
👍9
Какое ключевое слово используется для определения асинхронного метода?
Anonymous Quiz
94%
async
4%
await
2%
asynchronous
1%
parallel
😴17👍6🤡32😁2💩1🥴1🗿1
Какой символ используется для комментариев в одной строке?
Anonymous Quiz
96%
//
3%
/*
0%
''
1%
<!--
🤣35🥱19🤡9🥴4👍2🗿1
Do I need to run tests before push?

На текущем проекте мы используем Kafka. Так вышло, что я - MacBook enjoyer и пишу код на m1 машине.

Соответственно, интеграционные тесты, задействующие Kafka тупо не запускаются.
И какое-то время назад у меня в голове возник вопрос: «а должно ли это вообще меня волновать?»

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

▪️Эмулятор внешних систем (mock интеграций);

▪️Базы данных;

▪️Кэш;

▪️Gateway микросервисов;

И многое другое…

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

Смысл прогонять тесты на машине, если репорт будет читаться из пайплайна в гитлабе?

#полезное #tips
👍41🤣1
Какой оператор используется для фильтрации элементов в LINQ?
Anonymous Quiz
12%
select
74%
where
9%
orderby
5%
groupby
🥴11👍4💩4😁2
Как создать экземпляр класса в C#?
Anonymous Quiz
89%
MyClass obj = new MyClass();
3%
MyClass obj = MyClass();
2%
MyClass obj;
6%
obj = new MyClass();
🥴28🤡9🥱4👎1💩1🗿1
⚡️ Если я слышу, что на C# существует огромное количество сторонних библиотек и не нужно писать своих, я скидываю канал C# Academy.

В канале я научился:

• Создавать высоконагруженные приложения
• Строить правильную архитектуру приложения
• Как обрабатывать сотни тысяч запросов без падения сервисов
• Решать практические задачи с собеседований по С# и .Net
• Узнал огромное количество фич с кодом

Полная маст-хэв папка для С# разработчиков: https://yangx.top/addlist/P5AWf_YPuyBmMjMy

Подписывайся, правильно поданная, структурированная информация, это залог роста – @csharp_ci
👍6🔥31🤯1🤡1
Друзья, какая из рубрик канала вам нравится больше всего?

Вакансии - #вакансия
Статьи -
#полезное
Трюки и возможности языка -
#tips
Тесты -
#тест
Книги -
#книги

Напишите в комментариях, если хотите, чтобы мы что-то добавили - тоже в комменты.
👍11👎1