<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nomon</title>
    <description>The latest articles on DEV Community by Nomon (@nmatlubov).</description>
    <link>https://dev.to/nmatlubov</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2201945%2Fedd12dab-5c3c-4ad7-bcda-e24d058ad9c9.jpg</url>
      <title>DEV Community: Nomon</title>
      <link>https://dev.to/nmatlubov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nmatlubov"/>
    <language>en</language>
    <item>
      <title>Dependency Container and Services Lifetimes (На русском)</title>
      <dc:creator>Nomon</dc:creator>
      <pubDate>Mon, 18 Nov 2024 11:33:18 +0000</pubDate>
      <link>https://dev.to/nmatlubov/dependency-container-and-services-lifetimes-na-russkom-1gkk</link>
      <guid>https://dev.to/nmatlubov/dependency-container-and-services-lifetimes-na-russkom-1gkk</guid>
      <description>&lt;p&gt;&lt;strong&gt;Этот краткий блог про Dependency Container и Services Lifetimes в котором я объясню:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Что такое Dependency Container.&lt;/li&gt;
&lt;li&gt;Что такое Services Lifetimes.&lt;/li&gt;
&lt;li&gt;Что такое Hosted Service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Приятного чтения&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependency Container&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dependency Container - это инструмент который управляет жизненным компонента. DI  Контейнер отвечает за создание и удаление экземпляров необходимых служб, отслеживая их и поддерживая в течение всего срока службы. Если в вашей системе есть компоненты которые имеют свои зависимости, то класс знает что внедрять во все эти компоненты.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Service Lifetimes&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Service Lifetimes - DIC (Dependency Injection Container) имеет три типа жизненных циклов. Для создания каждого типа сервиса предназначен соответствующий метод AddTransient(), AddScoped() и AddSingleton().&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AddTransient при каждом обращении к сервису создается новый объект сервиса. В течение одного запроса может быть несколько обращений к сервису, соответственно при каждом обращении будет создаваться новый объект. Подобная модель жизненного цикла наиболее подходит для легковесных сервисов, которые не хранят данных о состоянии.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;builder.Services.AddTransient&amp;lt;IDependent, Dependent&amp;gt;();&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;AddSingleton объект сервиса создается при первом обращении к нему, все последующие запросы используют один и тот же ранее созданный объект сервиса&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;builder.Services.AddSingleton&amp;lt;IDependent, Dependent&amp;gt;();&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;AddScoped для каждого запроса создается свой объект сервиса. То есть если в течение одного запроса есть несколько обращений к одному сервису, то при всех этих обращениях будет использоваться один и тот же объект сервиса.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;builder.Services.AddScoped&amp;lt;IDependent, Dependent&amp;gt;();&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Тип службы указывается при регистрации службы в контейнере, поскольку служба может использоваться в разных местах приложения, срок службы службы будет влиять на то, будет ли один и тот же экземпляр службы использоваться во всем приложении, что повлияет на выходные данные.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Пример кода
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = new HostApplicationBuilder();

builder.Services.AddTransient&amp;lt;IDependent, Dependent&amp;gt;();
builder.Services.AddSingleton&amp;lt;ITimeProvider, TransientTimeProvider&amp;gt;();
builder.Services.AddScoped&amp;lt;IDependent, Dependent&amp;gt;();
builder.Services.AddHostedService&amp;lt;RunWhenStart&amp;gt;();

var application = builder.Build();

var scopeProvider = application.Services.GetRequiredService&amp;lt;IServiceScopeFactory&amp;gt;();

var service1 = application.Services.GetRequiredService&amp;lt;IDependent&amp;gt;();
service1.Run();

using (var scope = scopeProvider.CreateScope())
{
    var innerservice1 = scope.ServiceProvider.GetRequiredService&amp;lt;IDependent&amp;gt;();
    var innerservice2 = scope.ServiceProvider.GetRequiredService&amp;lt;IDependent&amp;gt;();

    innerservice1.Run();
    innerservice2.Run();
}

application.Run(); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Hosted Service&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hosted Service - Используется для запуска и завершения фоновых задач которые нужны для обработки запросов при запуске приложения а также для периодических проверок программы по типу health check, отправка телемитрии сервиса, инвалидация кэша. Hosted Service запускается при помощи вызова метода который наследует IHostedService и содержит два метода &lt;code&gt;StartAsync()&lt;/code&gt; и &lt;code&gt;StopAsync()&lt;/code&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Пример кода
&lt;/h2&gt;

&lt;p&gt;Вызов класса&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder.Services.AddHostedService&amp;lt;RunWhenStart&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Имплементация класса&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class RunWhenStart : IHostedService
{
    public async Task StartAsync(CancellationToken cancellationToken = default)
    {
        for (int i = 0; i &amp;lt; 10; i++)
        {
            Console.WriteLine("WEB APP STARTED " + i);
            await Task.Delay(1000, cancellationToken);
        }
    }

    public Task StopAsync(CancellationToken cancellationToken = default)
    {
        Console.WriteLine("WEB APP STOPPED");
        return Task.CompletedTask;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>aspnet</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Пересечение траекторий через области (C#)</title>
      <dc:creator>Nomon</dc:creator>
      <pubDate>Thu, 17 Oct 2024 12:13:52 +0000</pubDate>
      <link>https://dev.to/nmatlubov/pieriesiechieniie-traiektorii-chieriez-oblasti-c-2nf</link>
      <guid>https://dev.to/nmatlubov/pieriesiechieniie-traiektorii-chieriez-oblasti-c-2nf</guid>
      <description>&lt;p&gt;&lt;strong&gt;Задача:&lt;/strong&gt;&lt;br&gt;
Представьте, что у нас есть две точки на плоскости — принц и принцесса. Между ними находятся несколько планет, каждая из которых представлена окружностью с определённым радиусом. Наша цель — посчитать, сколько раз траектория, соединяющая принца и принцессу, пересекает границы этих планет.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Как мы решаем эту задачу:&lt;/strong&gt;&lt;br&gt;
Для этого я написал программу на C#, которая помогает вычислить количество таких пересечений. Давайте разберём её шаг за шагом.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Основной цикл программы&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CAMP.hw3;

int.TryParse(Console.ReadLine(), out var testCases);

while (testCases-- &amp;gt; 0)
{
    var addressParts = Console.ReadLine()?.Split(" ", StringSplitOptions.RemoveEmptyEntries)
        .Select(int.Parse)
        .ToArray() ?? [];

    var prince = new Pointt(addressParts[0], addressParts[1]);
    var princess = new Pointt(addressParts[2], addressParts[3]);

    int.TryParse(Console.ReadLine(), out var planetsCount);

    var crossing = 0;
    while(planetsCount-- &amp;gt; 0)
    {
        var Planet = new Planet(Console.ReadLine());

        var princeInside = Planet.Contains(prince);
        var princessInside = Planet.Contains(princess);
        var crosses = princeInside ^ princessInside;
        crossing += crosses ? 1 : 0; 
    }
    Console.WriteLine(crossing);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Что здесь происходит:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Программа начинает с того, что считывает количество тестов, которые нужно выполнить.&lt;/li&gt;
&lt;li&gt;Для каждого теста она считывает координаты принца и принцессы — это будут две точки на плоскости.&lt;/li&gt;
&lt;li&gt;Далее, программа узнаёт, сколько планет нужно учесть. Каждая планета описана своими координатами (центр окружности) и радиусом.&lt;/li&gt;
&lt;li&gt;Для каждой планеты проверяется: находится ли принц внутри планеты? А принцесса? Если один из них внутри планеты, а другой снаружи, это значит, что линия между ними пересекает границу планеты. Каждый такой пересечение добавляется в итоговый счётчик.&lt;/li&gt;
&lt;li&gt;В конце программы выводится количество пересечений для каждой пары принц-принцесса.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Описание структуры планеты&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace CAMP.hw3;

public struct Planet (Pointt center, int radious)
{
    public Pointt Center {get; init;} = center;
    public int Radious {get; init;} = radious;

    public Planet (string? parts) : this(new(), 0)
    {
        var parsedParts = parts?.Split(" ", StringSplitOptions.RemoveEmptyEntries)
            .Select(int.Parse)
            .ToArray() ?? [];

        Center = new Pointt(parsedParts[0], parsedParts[1]);
        Radious = parsedParts[3];
    }

    public bool Contains(Pointt point)
    {
        var a = Center.X - point.X;
        var b = Center.Y - point.Y;
        var cSquared = a * a + b * b;
        var c = Math.Sqrt(cSquared);

        return c &amp;lt;= Radious;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Объяснение:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Структура Planet описывает каждую планету как окружность на плоскости. У окружности есть центр и радиус.&lt;/li&gt;
&lt;li&gt;Когда мы создаём объект планеты, программа принимает строку с координатами и радиусом, разбирает её, инициализируя соответствующие параметры.&lt;/li&gt;
&lt;li&gt;Важная часть здесь — это метод Contains, который проверяет, находится ли точка (например, принц или принцесса) внутри планеты. Для этого вычисляется расстояние от центра планеты до точки, и если это расстояние меньше или равно радиусу планеты, значит точка находится внутри.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Описание структуры точки&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace CAMP.hw3;

public readonly struct Pointt (int x, int y)
{
    public int X {get; init;} = x;
    public int Y {get; init;} = y;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Что делает эта часть кода:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Структура Pointt описывает точку на плоскости с координатами X и Y.&lt;/li&gt;
&lt;li&gt;Эти значения инициализируются при создании объекта, и они доступны только для чтения (read-only), что делает точки неизменяемыми после их создания.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Итог:&lt;/strong&gt;&lt;br&gt;
В итоге программа эффективно решает задачу пересечения траекторий, проверяя для каждой планеты, пересекается ли она с отрезком между двумя точками. Структуры Planet и Pointt помогают описать ключевые объекты, а метод Contains использует простую геометрию для определения, попадает ли точка внутрь окружности.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>programming</category>
    </item>
    <item>
      <title>Нахождение дистанции на C# 🌍</title>
      <dc:creator>Nomon</dc:creator>
      <pubDate>Tue, 15 Oct 2024 08:17:57 +0000</pubDate>
      <link>https://dev.to/nmatlubov/nakhozhdieniie-distantsii-na-c-5f6o</link>
      <guid>https://dev.to/nmatlubov/nakhozhdieniie-distantsii-na-c-5f6o</guid>
      <description>&lt;p&gt;&lt;strong&gt;Введение&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;В этом посте я покажу, как сделать это с помощью C# и формулы гаверсина, одного из популярных способов расчета расстояния между двумя точками на поверхности Земли.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Что такое формула гаверсина?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Формула гаверсина используется для вычисления большой окружности — кратчайшего расстояния между двумя точками на поверхности сферы, в нашем случае — Земли. В отличие от простого "расстояния по прямой линии", эта формула учитывает кривизну Земли и поэтому дает более точные результаты при вычислении расстояний на большие расстояния (например, между городами или странами).&lt;/li&gt;
&lt;li&gt;Формула принимает в качестве входных данных широту и долготу двух точек и вычисляет расстояние между ними.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Как это работает в C#?&lt;/strong&gt;&lt;br&gt;
Ниже приведен код, который можно использовать для расчета расстояния между двумя географическими координатами (широта и долгота):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace day1{

    class Program (){

        static void Main(string[] args){
            // Запрашиваем ввод у пользователя
            Console.Write("Введите широту первой точки (например, вашего города): ");
            double lat1 = Convert.ToDouble(Console.ReadLine());

            Console.Write("Введите долготу первой точки: ");
            double lon1 = Convert.ToDouble(Console.ReadLine());

            Console.Write("Введите широту второй точки (например, другого города): ");
            double lat2 = Convert.ToDouble(Console.ReadLine());

            Console.Write("Введите долготу второй точки: ");
            double lon2 = Convert.ToDouble(Console.ReadLine());

            // Здесь вычисляем расстояние
            Distance distanceCalculator = new Distance();
            double distance = distanceCalculator.HaversineDistance(lat1, lon1, lat2, lon2);

            // Выводим результат
            Console.WriteLine($"Расстояние между точками: {distance:F2} километров.");
        }
    }


}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace day1{

    class Distance{

        const double EarthRadiusKm = 6371.0;

        public double HaversineDistance(double lat1, double lon1, double lat2, double lon2){
            // Переводим градусы в радианы, чтобы программа могла их использовать
            double dLat = DegreesToRadians(lat2 - lat1);
            double dLon = DegreesToRadians(lon2 - lon1);

            // Теперь используем формулу для расчета расстояния
            double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
            Math.Cos(DegreesToRadians(lat1)) * Math.Cos(DegreesToRadians(lat2)) *
            Math.Sin(dLon / 2) * Math.Sin(dLon / 2);

            double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));

            // Возвращаем результат — расстояние в километрах
            return EarthRadiusKm * c;
        }

            // Этот метод просто переводит градусы в радианы
        static double DegreesToRadians(double degrees){
            return degrees * Math.PI / 180;

        }

    }


}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Объяснение кода
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Ввод данных: Программа запрашивает у пользователя ввод широты и долготы двух точек.
&lt;strong&gt;Формула гаверсина:&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;Мы используем формулу гаверсина для вычисления расстояния, чтобы учесть кривизну Земли.
&lt;strong&gt;Вывод результата:&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;После вычислений программа выводит результат — расстояние между двумя точками в километрах.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Как это работает?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Мы конвертируем широту и долготу из градусов в радианы, так как многие математические функции работают с радианами.&lt;/li&gt;
&lt;li&gt;Затем используем саму формулу гаверсина для вычисления большого окружного расстояния между двумя точками на сфере.
В конце программа возвращает результат в километрах.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Если у вас есть вопросы или предложения по улучшению программы, обязательно оставляйте комментарии!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>programming</category>
    </item>
    <item>
      <title>#1 Первый урок</title>
      <dc:creator>Nomon</dc:creator>
      <pubDate>Sat, 12 Oct 2024 17:51:55 +0000</pubDate>
      <link>https://dev.to/nmatlubov/1-piervyi-urok-23ej</link>
      <guid>https://dev.to/nmatlubov/1-piervyi-urok-23ej</guid>
      <description>&lt;h2&gt;
  
  
  Основные команды Windows для работы с терминалом.
&lt;/h2&gt;

&lt;p&gt;Сегодня мы познакомились с терминалом Windows и разобрали несколько базовых команд, которые должен знать каждый разработчик. Эти команды позволяют эффективно управлять файлами и директориями, упрощая работу с проектами и настройками системы.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Команды:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;cd (Change Directory)&lt;/strong&gt;&lt;br&gt;
Эта команда используется для изменения текущей директории. С её помощью можно перемещаться между папками и дисками. Например, команда &lt;strong&gt;cd&lt;/strong&gt; &lt;strong&gt;C:\Projects&lt;/strong&gt; перенесёт вас в папку &lt;strong&gt;"Projects"&lt;/strong&gt; на диске &lt;strong&gt;C&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;mkdir (Make Directory)&lt;/strong&gt;&lt;br&gt;
Команда для создания новой директории (или проще говоря, папки). Если вам нужно создать папку, скажем, для нового проекта, используйте &lt;strong&gt;mkdir&lt;/strong&gt; &lt;strong&gt;MyNewProject&lt;/strong&gt;. Теперь в текущей директории появится новая папка &lt;strong&gt;"MyNewProject"&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;clear&lt;/strong&gt;&lt;br&gt;
Как видно из названия, команда очищает окно терминала от предыдущих команд и вывода. Это полезно, когда нужно освежить рабочее пространство в терминале.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;dir / ls&lt;/strong&gt;&lt;br&gt;
Эти команды отображают содержимое текущей директории. &lt;strong&gt;dir&lt;/strong&gt; используется в Windows, а &lt;strong&gt;ls&lt;/strong&gt; — аналогичная команда в системах Linux и MacOS. Они позволяют быстро увидеть, какие файлы и папки находятся в выбранной директории.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;rmdir (Remove Directory)&lt;/strong&gt;&lt;br&gt;
Эта команда удаляет пустые директории. Например, если папка больше не нужна и она пустая, вы можете её удалить с помощью команды &lt;strong&gt;rmdir FolderName&lt;/strong&gt;. Если папка не пуста, нужно сначала удалить все её содержимое.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;del (Delete)&lt;/strong&gt;&lt;br&gt;
Команда для удаления файлов. Если вам нужно удалить конкретный файл, используйте &lt;strong&gt;del FileName&lt;/strong&gt;. Она не работает для удаления директорий — для этого используйте &lt;strong&gt;rmdir&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;exit&lt;/strong&gt;&lt;br&gt;
Эта команда завершает работу терминала, закрывая окно командной строки.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
