Полиморфизм подтипов — это способность объектов разных классов, связанных отношениями наследования, обрабатываться единообразно. Это позволяет использовать объекты подклассов через ссылки на базовые классы, что делает код гибким и расширяемым.
Классы могут наследовать другие классы, унаследуя их методы и свойства.
Классы могут реализовывать интерфейсы, обеспечивая конкретную реализацию методов интерфейса.
Методы, объявленные как
virtual в базовом классе, могут быть переопределены в производных классах с использованием ключевого слова override.Метод, который будет вызван, определяется во время выполнения, а не во время компиляции.
Базовый класс и производные классы
public class Animal
{
// Виртуальный метод, который может быть переопределен в производных классах
public virtual void Speak()
{
Console.WriteLine("Animal speaks");
}
}
public class Dog : Animal
{
// Переопределение метода Speak для класса Dog
public override void Speak()
{
Console.WriteLine("Dog barks");
}
}
public class Cat : Animal
{
// Переопределение метода Speak для класса Cat
public override void Speak()
{
Console.WriteLine("Cat meows");
}
}
Использование полиморфизма подтипов
class Program
{
static void Main()
{
// Создание массива объектов типа Animal
Animal[] animals = new Animal[]
{
new Dog(),
new Cat(),
new Animal()
};
// Вызов метода Speak для каждого объекта в массиве
foreach (Animal animal in animals)
{
animal.Speak();
}
}
}
Полиморфизм также может быть достигнут через интерфейсы. В этом примере классы
Dog и Cat реализуют интерфейс IAnimal, и метод Speak вызывается через интерфейс, что также демонстрирует полиморфизм подтипов.public interface IAnimal
{
void Speak();
}
public class Dog : IAnimal
{
public void Speak()
{
Console.WriteLine("Dog barks");
}
}
public class Cat : IAnimal
{
public void Speak()
{
Console.WriteLine("Cat meows");
}
}
class Program
{
static void Main()
{
IAnimal[] animals = new IAnimal[]
{
new Dog(),
new Cat()
};
foreach (IAnimal animal in animals)
{
animal.Speak();
}
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4👾3
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥4❤1👀1
Принцип подстановки Барбары Лисков (Liskov Substitution Principle, LSP) является одним из пяти принципов объектно-ориентированного программирования, известных под акронимом SOLID.
Основная идея заключается в том, что если класс
B является подтипом класса A, то объекты класса A могут быть заменены объектами класса B без изменения правильности работы программы. Это означает, что наследование должно использоваться так, чтобы производный класс сохранял поведение базового класса.Производный класс должен соблюдать контракт, определённый базовым классом. Это включает в себя сигнатуры методов и ожидания (предусловия и постусловия).
Инварианты, или неизменяемые условия, которые выполняются для объектов базового класса, должны оставаться в силе и для объектов производного класса.
Производный класс не должен ослаблять постусловия методов базового класса. Постусловия - это условия, которые гарантированы после выполнения метода.
Производный класс не должен усиливать предусловия методов базового класса. Предусловия - это условия, которые должны быть выполнены перед вызовом метода. В этом примере
Penguin нарушает LSP, так как он не может летать. Если заменить экземпляр FlyingBird на Penguin, программа перестанет работать правильно. public abstract class Bird
{
public abstract void Fly();
}
public class FlyingBird : Bird
{
public override void Fly()
{
Console.WriteLine("I can fly!");
}
}
public class Penguin : Bird
{
public override void Fly()
{
throw new NotSupportedException("Penguins cannot fly.");
}
}
Теперь классы
FlyingBird и Penguin оба наследуют класс Bird и реализуют метод Move, но каждый делает это по-своему, не нарушая LSP.public abstract class Bird
{
public abstract void Move();
}
public class FlyingBird : Bird
{
public override void Move()
{
Fly();
}
private void Fly()
{
Console.WriteLine("I can fly!");
}
}
public class Penguin : Bird
{
public override void Move()
{
Console.WriteLine("I waddle.");
}
}
Код, который соблюдает LSP, легче модифицировать и расширять без риска нарушения существующей функциональности.
Код, соответствующий LSP, легче тестировать, так как можно заменять объекты их подтипами в тестах без изменения поведения.
Такой код легче поддерживать и рефакторить, так как контракт между базовым и производным классами чётко определён и соблюдается.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥8
Существует несколько типов данных, которые можно разделить на основные категории: простые типы, ссылочные типы, и пользовательские типы.
Простые типы хранят значения непосредственно и включают примитивные типы, перечисления и структуры.
Целочисленные типы:
byte (8-битный, от 0 до 255)sbyte (8-битный, от -128 до 127)short (16-битный, от -32,768 до 32,767)ushort (16-битный, от 0 до 65,535)int (32-битный, от -2,147,483,648 до 2,147,483,647)uint (32-битный, от 0 до 4,294,967,295)long (64-битный, от -9,223,372,036,854,775,808 до 9,223,372,036,854,775,807)ulong (64-битный, от 0 до 18,446,744,073,709,551,615)float (32-битный, ±1.5e−45 до ±3.4e38, 7 знаков точности)double (64-битный, ±5.0e−324 до ±1.7e308, 15-16 знаков точности)decimal (128-битный, ±1.0 × 10−28 до ±7.9 × 10^28, 28-29 знаков точности)char (16-битный символ Unicode)bool (логический тип, принимает значения true или false)Структуры (struct): Пользовательские типы данных, которые являются значимыми типами и могут содержать поля, методы, свойства и т.д.
Перечисления (enum): Тип, представляющий набор именованных констант.
Ссылочные типы хранят ссылку на область памяти, где находятся данные. К ним относятся классы, интерфейсы, делегаты и массивы.
class): Основной строительный блок объектно-ориентированного программирования, могут содержать поля, методы, свойства, события и т.д.
interface): Контракты, определяющие набор методов и свойств, которые должны быть реализованы классами.
delegate): Типы, представляющие ссылку на методы. Используются для реализации обратных вызовов и событий.
event): Механизм, через который объекты могут сообщать о произошедших действиях.
Array): Коллекции элементов одного типа, доступ к которым осуществляется по индексу.
string): Неизменяемые последовательности символов.
Пользовательские типы могут быть созданы на основе простых и ссылочных типов.
Tuple): Группировка значений различных типов.
Типы, созданные для хранения наборов значений, определённых на лету.
Позволяют значимым типам принимать значение
null.int? nullableInt = null; // Nullable int
Пример использования простых типов:
int age = 30;
double salary = 50000.50;
bool isEmployed = true;
char grade = 'A';
Пример использования классов и интерфейсов:
public interface IAnimal
{
void Speak();
}
public class Dog : IAnimal
{
public void Speak()
{
Console.WriteLine("Bark");
}
}
Пример использования структуры:
public struct Point
{
public int X;
public int Y;
public Point(int x, int y)
{
X = x;
Y = y;
}
}
Пример использования перечисления:
public enum DaysOfWeek
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🔥4
Это концепция из теории автоматов и программирования, которая описывает поведение системы на основе различных состояний и переходов между ними. Она позволяет моделировать сложные системы и процессы, управляя переходами между разными состояниями в зависимости от входных данных или событий.
Позволяет разбить сложную логику на более простые, управляемые состояния.
Описывает, как система реагирует на различные события.
Легче понять и изменить поведение системы, когда оно описано в виде состояний и переходов.
Для управления поведением персонажей.
В промышленной автоматике.
Для управления состояниями интерфейсов и переходами между ними.
Для управления последовательностью сообщений и реакцией на них.
using System;
public enum TrafficLightState
{
Red,
Green,
Yellow
}
public class TrafficLight
{
private TrafficLightState _state;
public TrafficLight()
{
_state = TrafficLightState.Red;
}
public void ChangeState()
{
switch (_state)
{
case TrafficLightState.Red:
_state = TrafficLightState.Green;
break;
case TrafficLightState.Green:
_state = TrafficLightState.Yellow;
break;
case TrafficLightState.Yellow:
_state = TrafficLightState.Red;
break;
}
Console.WriteLine($"Состояние светофора: {_state}");
}
}
class Program
{
static void Main()
{
TrafficLight trafficLight = new TrafficLight();
trafficLight.ChangeState(); // Состояние светофора: Green
trafficLight.ChangeState(); // Состояние светофора: Yellow
trafficLight.ChangeState(); // Состояние светофора: Red
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14😁5🤔1👀1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🔥4
Позволяют определять конструкторы прямо в объявлении класса или структуры, что упрощает код и улучшает его читаемость.
public class Person(string name, int age)
{
public string Name { get; } = name;
public int Age { get; } = age;
}
Обеспечивает более удобный синтаксис для создания коллекций.
var numbers = [1, 2, 3, 4, 5];
Теперь можно задавать значения по умолчанию для auto-properties, что делает код более лаконичным.
public string Name { get; set; } = "Unknown";Позволяет использовать алиасы для пространств имен, улучшая читаемость кода.
using Text = System.Text;
Улучшены возможности для работы с лямбда-выражениями, делая их более гибкими и мощными.
Эти нововведения направлены на упрощение синтаксиса языка, улучшение читаемости и поддерживаемости кода, а также на повышение производительности и удобства разработки.
public class Program
{
public static void Main()
{
var person = new Person("John", 30);
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
var numbers = [1, 2, 3, 4, 5];
numbers.ForEach(n => Console.WriteLine(n));
var name = new Name { Value = "Unknown" };
Console.WriteLine(name.Value);
}
}
public class Person(string name, int age)
{
public string Name { get; } = name;
public int Age { get; } = age;
}
public class Name
{
public string Value { get; set; } = "Default Name";
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12
Включает в себя ряд улучшений и нововведений, связанных с асинхронным программированием, а именно с использованием ключевых слов
async и await. Эти изменения направлены на повышение производительности и удобства использования асинхронных методов.В .NET 8 были проведены оптимизации, которые улучшают производительность асинхронных операций. Это включает более эффективное управление задачами (
Task), снижение накладных расходов на создание и завершение задач.Внутренние изменения в библиотеке обеспечивают более эффективное управление асинхронными потоками, что приводит к улучшению производительности приложений, активно использующих асинхронные операции.
В .NET 8 добавлены новые возможности для диагностики и мониторинга асинхронных операций, что помогает разработчикам лучше понимать и оптимизировать асинхронное выполнение в их приложениях.
Асинхронные методы позволяют выполнять длительные операции, такие как ввод-вывод или сетевые запросы, без блокировки основного потока выполнения. Вот пример использования
async и await:using System;
using System.Net.Http;
using System.Threading.Tasks;
public class Program
{
public static async Task Main(string[] args)
{
string url = "https://api.example.com/data";
string result = await FetchDataAsync(url);
Console.WriteLine(result);
}
public static async Task<string> FetchDataAsync(string url)
{
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
string responseData = await response.Content.ReadAsStringAsync();
return responseData;
}
}
}
Оптимизация асинхронных операций позволяет приложениям обрабатывать большее количество запросов и задач за единицу времени, что особенно важно для серверных приложений и веб-сервисов.
Улучшенные инструменты и библиотеки облегчают написание, отладку и мониторинг асинхронного кода, что делает разработку более продуктивной.
Асинхронные операции позволяют приложениям лучше масштабироваться, эффективно распределяя ресурсы и минимизируя задержки.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥1
Это промежуточный этап или путь в каком-либо процессе, который служит связующим звеном между двумя основными этапами или состояниями. Этот термин часто используется в различных контекстах, таких как управление проектами, разработка программного обеспечения или личностный рост, обозначая стадию, на которой происходит переход или подготовка к финальному результату.
Middleware может перехватывать и изменять HTTP-запросы перед их передачей на основной сервер или конечную точку обработки.
Middleware также может перехватывать и изменять HTTP-ответы перед их отправкой клиенту.
Middleware может использоваться для проверки подлинности пользователей и определения их прав доступа.
Middleware может записывать информацию о запросах и ответах для целей мониторинга и отладки.
Middleware может перехватывать и обрабатывать ошибки, возникающие во время обработки запросов.
Мiddleware компоненты добавляются в конвейер обработки запросов через метод
Configure в классе Startup.public class Startup
{
public void Configure(IApplicationBuilder app)
{
// Пример простого middleware, который логирует каждый запрос
app.Use(async (context, next) =>
{
Console.WriteLine($"Request: {context.Request.iss.onethod} {context.Request.Path}");
await next.Invoke();
Console.WriteLine($"Response: {context.Response.StatusCode}");
});
// Добавление стандартного middleware для обработки статических файлов
app.UseStaticFiles();
// Добавление стандартного middleware для маршрутизации
app.UseRouting();
// Конечная точка обработки запросов
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello, World!");
});
});
}
}
Middleware позволяет разбивать обработку запросов на отдельные компоненты, каждый из которых отвечает за свою часть логики.
Один и тот же middleware может использоваться в разных частях приложения или даже в разных приложениях.
Middleware можно легко добавлять, удалять или заменять, что упрощает модификацию и расширение приложения.
Разделение логики на отдельные компоненты делает код более структурированным и легким для поддержки.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🤔2🤯2👾2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🤔1👾1
Представляет собой последовательность компонентов middleware, через которые проходит HTTP-запрос, начиная с момента его получения сервером и до отправки ответа клиенту. Каждый компонент в конвейере выполняет определенные задачи, такие как аутентификация, авторизация, логирование, обработка ошибок и так далее. Конвейер позволяет легко управлять обработкой запросов, добавляя или удаляя компоненты middleware.
Когда сервер получает HTTP-запрос, он передается в первый компонент middleware в конвейере.
Запрос проходит через каждый компонент middleware последовательно.
Каждый компонент может:
Обрабатывать запрос и передать его следующему компоненту.
Обрабатывать запрос и завершить его обработку, не передавая дальше.
Внести изменения в запрос или ответ.
Компонент middleware может передать управление следующему компоненту, вызывая метод
next.Invoke(). После завершения обработки запроса следующим компонентом, управление возвращается обратно к предыдущему компоненту.Когда запрос доходит до конца конвейера и обработка завершается, ответ формируется и проходит обратно через все компоненты middleware в обратном порядке, что позволяет им вносить изменения в ответ перед его отправкой клиенту.
Настройка конвертатора обработки запросов в ASP.NET Core:
public class Startup
{
public void Configure(IApplicationBuilder app)
{
// Логирование запросов
app.Use(async (context, next) =>
{
Console.WriteLine($"Request: {context.Request.iss.onethod} {context.Request.Path}");
await next.Invoke();
Console.WriteLine($"Response: {context.Response.StatusCode}");
});
// Обработка статических файлов
app.UseStaticFiles();
// Маршрутизация
app.UseRouting();
// Аутентификация
app.UseAuthentication();
// Авторизация
app.UseAuthorization();
// Конечные точки обработки запросов
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello, World!");
});
});
}
}
Конвейер позволяет легко добавлять и удалять компоненты, изменяя способ обработки запросов.
Каждый компонент middleware выполняет свою задачу, что делает код более структурированным и легким для поддержки.
Можно легко добавить новые компоненты для обработки различных аспектов запросов, таких как кэширование, компрессия и другие.
Один и тот же компонент middleware может быть использован в разных приложениях, что снижает дублирование кода.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥5
Используются для выполнения логики до и после выполнения метода действия контроллера. Они предоставляют механизм для выполнения кросс-секционных задач, таких как логирование, обработка исключений, валидация и т.д. Action фильтры реализуют интерфейс
IActionFilter или IAsyncActionFilter.Этот метод вызывается перед выполнением метода действия. Здесь можно добавить логику, которая будет выполняться до вызова действия, например, логирование или проверка условий.
public void OnActionExecuting(ActionExecutingContext context)
{
// Логика до выполнения действия
}
Этот метод вызывается после выполнения метода действия. Здесь можно добавить логику, которая будет выполняться после вызова действия, например, логирование результатов или модификация ответа.
public void OnActionExecuted(ActionExecutedContext context)
{
// Логика после выполнения действия
}
Этот метод объединяет функциональность
OnActionExecuting и OnActionExecuted в одном асинхронном методе. Здесь можно определить логику, которая будет выполняться как до, так и после выполнения метода действия.public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// Логика до выполнения действия
var resultContext = await next();
// Логика после выполнения действия
}
Синхронный Action фильтр:
public class SampleActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// Логика до выполнения действия
Console.WriteLine("Before executing action");
}
public void OnActionExecuted(ActionExecutedContext context)
{
// Логика после выполнения действия
Console.WriteLine("After executing action");
}
}
Асинхронный Action фильтр:
public class SampleAsyncActionFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// Логика до выполнения действия
Console.WriteLine("Before executing action");
var resultContext = await next();
// Логика после выполнения действия
Console.WriteLine("After executing action");
}
}
Action фильтр можно применять к контроллерам или действиям контроллера с помощью атрибута
[ServiceFilter] или [TypeFilter]. Также его можно зарегистрировать глобально в Startup.cs.Применение к контроллеру или действию:
[ServiceFilter(typeof(SampleActionFilter))]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
Глобальная регистрация:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(config =>
{
config.Filters.Add(typeof(SampleActionFilter));
});
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥1
Определяет, как сообщения от производителей (producers) направляются в очереди через обменники (exchanges).
Отправляют сообщения в обменники.
Направляют сообщения в очереди на основе привязок (bindings) и типа обменника:
Direct Exchange: Сообщения направляются в очереди, соответствующие точному ключу маршрутизации.
Topic Exchange: Направляет сообщения в очереди по шаблону ключа маршрутизации.
Fanout Exchange: Широковещательно отправляет сообщения во все очереди, связанные с обменником.
Headers Exchange: Использует заголовки сообщений для маршрутизации.
Получают сообщения от обменников.
Связывают обменники с очередями и определяют правила маршрутизации.
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='direct_logs', exchange_type='direct')
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.iss.onethod.queue
channel.queue_bind(exchange='direct_logs', queue=queue_name, routing_key='info')
connection.close()
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='direct_logs', exchange_type='direct')
routing_key = 'info'
message = 'Hello, RabbitMQ!'
channel.basic_publish(exchange='direct_logs', routing_key=routing_key, body=message)
connection.close()
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='direct_logs', exchange_type='direct')
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.iss.onethod.queue
channel.queue_bind(exchange='direct_logs', queue=queue_name, routing_key='info')
def callback(ch, method, properties, body):
print(f"Received {body}")
channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True)
print('Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
😁7👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥3
Сообщения направляются в очереди, которые связаны с обменником, если ключ маршрутизации сообщения точно совпадает с ключом маршрутизации, указанным в привязке. Логирование сообщений с разными уровнями важности, где каждая очередь получает сообщения с определенным уровнем (например, "info", "warning", "error").
channel.ExchangeDeclare(exchange: "direct_logs", type: "direct");
Сообщения направляются в очереди на основе шаблонов ключей маршрутизации. Поддерживаются подстановочные знаки:
* (заменяет одно слово) и # (заменяет ноль или более слов). Маршрутизация сообщений в зависимости от нескольких критериев, например, "logs.error", "logs.info.user".channel.ExchangeDeclare(exchange: "topic_logs", type: "topic");
Широковещательно отправляет сообщения во все очереди, связанные с этим обменником, игнорируя ключ маршрутизации. Широковещательная рассылка сообщений всем подписчикам, например, рассылка уведомлений.
channel.ExchangeDeclare(exchange: "logs", type: "fanout");
Направляет сообщения в очереди на основе заголовков сообщений, а не ключей маршрутизации. Можно задавать правила маршрутизации с использованием заголовков. Маршрутизация сообщений на основе различных свойств, таких как content-type или любые другие произвольные атрибуты.
channel.ExchangeDeclare(exchange: "headers_logs", type: "headers");
Direct
using RabbitMQ.Client;
var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.ExchangeDeclare(exchange: "direct_logs", type: "direct");
var queueName = channel.QueueDeclare().QueueName;
channel.QueueBind(queue: queueName, exchange: "direct_logs", routingKey: "info");
connection.Close();
Topic
using RabbitMQ.Client;
var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.ExchangeDeclare(exchange: "topic_logs", type: "topic");
var queueName = channel.QueueDeclare().QueueName;
channel.QueueBind(queue: queueName, exchange: "topic_logs", routingKey: "logs.*.user");
connection.Close();
Fanout
using RabbitMQ.Client;
var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.ExchangeDeclare(exchange: "logs", type: "fanout");
var queueName = channel.QueueDeclare().QueueName;
channel.QueueBind(queue: queueName, exchange: "logs", routingKey: "");
connection.Close();
Headers
using RabbitMQ.Client;
var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.ExchangeDeclare(exchange: "headers_logs", type: "headers");
var queueName = channel.QueueDeclare().QueueName;
var headers = new Dictionary<string, object>
{
{ "x-match", "all" },
{ "key1", "value1" },
{ "key2", "value2" }
};
channel.QueueBind(queue: queueName, exchange: "headers_logs", routingKey: "", arguments: headers);
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1