Что такое .NET?
.NET это фреймворк (платформа), написанный компанией Microsoft для создания множества разных типов приложений. Почему фреймворк назвали именно так, до сих пор до конца не ясно.
.NET позволяет работать со множеством языков - C#, F#, Visual Basic. C#, как вы поняли самый популярный.
На сегодняшний день, современным видением платформы то, что выросло из .NET Core. То есть, курс на кросс-платформенность и отсутствие привязки к операционной системе Windows. Тут уже и приложения быстрее, и можно собрать приложение из микросервисов в Docker контейнерах.
Что можно сделать с помощью .NET?
Веб, мобилки, десктоп, ML, геймдев, IoT и так далее.
Но люди все равно выберут Java, поэтому пожелаем роста платформе!
Если хотите узнать больше о платформе .NET, поделитесь этим в комментариях!
#полезное #tips
.NET это фреймворк (платформа), написанный компанией Microsoft для создания множества разных типов приложений. Почему фреймворк назвали именно так, до сих пор до конца не ясно.
.NET позволяет работать со множеством языков - C#, F#, Visual Basic. C#, как вы поняли самый популярный.
На сегодняшний день, современным видением платформы то, что выросло из .NET Core. То есть, курс на кросс-платформенность и отсутствие привязки к операционной системе Windows. Тут уже и приложения быстрее, и можно собрать приложение из микросервисов в Docker контейнерах.
Что можно сделать с помощью .NET?
Веб, мобилки, десктоп, ML, геймдев, IoT и так далее.
Но люди все равно выберут Java, поэтому пожелаем роста платформе!
Если хотите узнать больше о платформе .NET, поделитесь этим в комментариях!
#полезное #tips
👍16🔥1
👎22💩2
Freeze
/Inject
/Register
в AutoFixtureДавным-давно, в первых версиях библиотеки балом правил
Register
. Два других метода ещё не существовали.Определён он был следующим образом:
public static void Register<T>(this IFixture fixture, T item)
Однако, была и перегрузка:public static void Register<T>(this IFixture fixture, Func<T> creator)
Какое-то время казалось, что это нормально, впрочем, вскоре пользователи стали путаться. Например, можно было написать следующий код:fixture.Register(() => universe.LightUp());
Поскольку делегат может получаться путём приведения ссылкой на метод, то валидной была и следующая запись:fixture.Register(universe.LightUp);
Что если universe.LightUp
это обращение к свойству, а не к методу? Тогда была бы выбрана первая перегрузка.Но это крайне неочевидно.
Поэтому первая перегрузка превратилась в
Inject<T>(this IFixture fixture, T item)
.У метода
Freeze
несколько другая история.В прошлом оказалось, что достаточно часто встречается следующее использование AutoFixture в императивном стиле:
var foo = fixture.Create<Foo>();
fixture.Inject(foo);
Тогда, автор библиотеки решил, что это так называемая концепция заморозки.В итоге два вызова превратились в один метод
Freeze
.#полезное #tips
👍4
Какую самую главную ошибку совершают новички в ООП?
Начав изучать ООП, многие знакомятся с его тремя столпами: инкапсуляция, наследование и полиморфизм. Но удаётся ли правильно понять все из них?
Если выполнить поиск определения инкапсуляции в Google, то можно получить примерно следующее:
«Инкапсуляция в программировании — это принцип, согласно которому внутреннее устройство сущностей нужно объединять в специальной «оболочке» и скрывать от вмешательств извне.»
А теперь вспомним, что самыми популярными объектно-ориентированными языками программирования являются Java и C#, где модификаторы доступа (
На самом же деле, корректнее привести следующее определение:
«Инкапсуляция – это объединение в рамках одной структуры функций и данных, с которыми эти функции работают.»
То есть, в случае объектно-ориентированного программирования, создав некоторый объект, мы связали его данные с определёнными методами на всё время его жизни.
А в случае, например, обычных функций мы просто описали некий алгоритм, который описывает последовательность действий никак не связанных с некоторым состоянием.
Вот простой пример, чтобы понять разницу:
Начав изучать ООП, многие знакомятся с его тремя столпами: инкапсуляция, наследование и полиморфизм. Но удаётся ли правильно понять все из них?
Если выполнить поиск определения инкапсуляции в Google, то можно получить примерно следующее:
«Инкапсуляция в программировании — это принцип, согласно которому внутреннее устройство сущностей нужно объединять в специальной «оболочке» и скрывать от вмешательств извне.»
А теперь вспомним, что самыми популярными объектно-ориентированными языками программирования являются Java и C#, где модификаторы доступа (
private
, public
, protected
, etc.) это одни из самых используемых ключевых слов. И получается, что начинающие программисты путают сокрытие с инкапсуляцией.На самом же деле, корректнее привести следующее определение:
«Инкапсуляция – это объединение в рамках одной структуры функций и данных, с которыми эти функции работают.»
То есть, в случае объектно-ориентированного программирования, создав некоторый объект, мы связали его данные с определёнными методами на всё время его жизни.
А в случае, например, обычных функций мы просто описали некий алгоритм, который описывает последовательность действий никак не связанных с некоторым состоянием.
Вот простой пример, чтобы понять разницу:
class Doubler
{
private readonly int value;
public Doubler(int value) => this.value = value;
public int Double() => this.value * 2;
}
//…
public int Double(int value) => value * 2;
#полезное #tips❤16👍2
Что делает try-catch?
Anonymous Quiz
1%
Работает с файлами
2%
Работает с базой данных
2%
Работает с классами
96%
Работает с исключениями
🥴17🤡11💩7👍1
Многоликая регистрация в стандартном контейнере
Допустим, у нас есть некоторый класс, который реализует более одного интерфейса:
Попытавшись совершить регистрацию наивным путём, мы потерпим неудачу, зависимости будут ссылаться на разные экземпляры
Допустим, у нас есть некоторый класс, который реализует более одного интерфейса:
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>();#полезное #tips
services.AddSingleton<IFoo>(x => x.GetRequiredService<FooBar>());
services.AddSingleton<IBar>(x => x.GetRequiredService<FooBar>());
👍31
Пусть объявлен кортеж: var tuple = (5, 10). Как обратиться к значению 5?
Anonymous Quiz
30%
tuple[0]
56%
tuple.Item1
8%
tuple.first
5%
tuple.5
😁3
Autofac. Именованные сервисы
Контейнер Autofac предоставляет возможность внедрять конкретные зависимости, явно указывая некоторый ключ, который соотносится с желаемой зависимостью.
Например, у нас есть сервис
Чтобы указать, что мы хотим внедрить конкретную реализацию
По указанному ключу, он проведёт фильтрацию и выберет нужную зависимость.
Пример:
Контейнер Autofac предоставляет возможность внедрять конкретные зависимости, явно указывая некоторый ключ, который соотносится с желаемой зависимостью.
Например, у нас есть сервис
IDisplay
, отображающий какие-то произведения искусства IArtwork
.Чтобы указать, что мы хотим внедрить конкретную реализацию
MyPainting
, можно использовать атрибут KeyFilterAttribute
.По указанному ключу, он проведёт фильтрацию и выберет нужную зависимость.
Пример:
public class ArtDisplay : IDisplay#полезное #tips
{
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();
❤4👍2🤔2❤🔥1
Знали ли вы...
Что в .NET 7 при разработке API больше не требуется явно указывать атрибут
Теперь биндинг параметров у действий в контроллерах также отслеживает то, что приходит из DI контейнера.
Соответственно, такой код спокойно отработает без ошибок:
#полезное #tips
Что в .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
10%
От структуры так же, как и от класса, можно наследоваться
14%
В структуре нельзя определять конструктор
77%
Структура является значимым типом, а класс - ссылочным
🥱16👍5
Какой тип данных используется для хранения символов?
Anonymous Quiz
9%
string
89%
char
2%
byte
1%
short
🥴18🥱6😁3💩3👍2👎2🤯2🦄2🐳1🗿1
Как изменить таймаут для конкретного запроса в
Одной из лучших практик по работе с
Однако, возникают ситуации, когда для разных запросов требуется разное поведение клиента. Например, разные таймауты.
Проблема в том, что
Но я бы не писал этот пост, если бы не существовало решения проблемы. А решение довольно простое:
1️⃣ Пользовательский таймаут меньше того, что установлен в
#полезное #tips
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
83%
3%
JDBC
9%
ODBC
5%
DBI
marker interface
Для чего их вообще используют?
Допустим, в коде используется некий объект, который реализует указанный интерфейс. Тогда, появляется возможность проверить реализуется ли он и скорректировать на основе этого обработку объекта.
Также, маркерный интерфейс может быть необходимым злом при отсутствии поддержки в языке discriminated union types.
К сожалению, в объектно-ориентированных языках вроде C# объявить тип, который будет чем-то конкретным из указанного набора, невозможно.
Поэтому, приходится прибегать к таким уловкам.
Почему маркерных интерфейсов стоит избегать?
Главная проблема такого подхода - нарушение инкапсуляции.
Объект сам по себе теперь обладает неявным контролем над возможностями внешнего использования. Более того, он знает окружение, в котором будет использоваться.
Применение маркерного интерфейса подразумевает, что где-то будет находится проверка на этот маркер. Это противоречит идее инкапсуляции, потому что у объекта появляется знание о реализации той части системы, которая находится совершенно вне зоны его «полномочий».
В общем, обычный интерфейс говорит окружающему миру о том как он может быть использован, пустой, маркерный, о том, как должен быть использован.
#полезное #tips
Для чего их вообще используют?
Допустим, в коде используется некий объект, который реализует указанный интерфейс. Тогда, появляется возможность проверить реализуется ли он и скорректировать на основе этого обработку объекта.
Также, маркерный интерфейс может быть необходимым злом при отсутствии поддержки в языке 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