Ответ
Interceptor (Перехватчик) — это паттерн проектирования, который позволяет перехватывать вызовы методов или обработку запросов для добавления сквозной функциональности (cross-cutting concerns) без модификации основного кода бизнес-логики.
Основные цели:
- Логирование вызовов методов и их параметров.
- Кэширование результатов дорогостоящих операций.
- Валидация и авторизация входящих данных.
- Управление транзакциями (открытие/закрытие, откат).
- Измерение производительности (профилирование).
Реализация в C#: Чаще всего реализуется через:
- Аспектно-ориентированное программирование (AOP) с использованием библиотек (Castle DynamicProxy, PostSharp).
- Паттерн Декоратор для оборачивания сервисов.
- Фильтры в ASP.NET Core (Action Filters, Resource Filters).
Практический пример с Castle.DynamicProxy:
using Castle.DynamicProxy;
// 1. Определяем перехватчик
public class LoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine($"[LOG] Вызов метода: {invocation.Method.Name}");
Console.WriteLine($"[LOG] Аргументы: {string.Join(", ", invocation.Arguments)}");
var watch = Stopwatch.StartNew();
invocation.Proceed(); // Продолжаем выполнение оригинального метода
watch.Stop();
Console.WriteLine($"[LOG] Метод выполнен за {watch.ElapsedMilliseconds} мс");
Console.WriteLine($"[LOG] Результат: {invocation.ReturnValue}");
}
}
// 2. Создаем прокси-объект с перехватчиком
public interface IService { void ProcessData(string data); }
public class MyService : IService
{
public virtual void ProcessData(string data) { /* Логика */ }
}
var generator = new ProxyGenerator();
IService proxy = generator.CreateClassProxy<MyService>(new LoggingInterceptor());
// 3. Вызов будет перехвачен
proxy.ProcessData("test");
Ключевые нюансы:
- Для перехвата методов классов (не интерфейсов) методы должны быть помечены как
virtual. - Создание прокси и перехват вносят небольшие накладные расходы на производительность.
- Важно избегать побочных эффектов в перехватчиках, которые могут нарушить основную логику.