Skip to content

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

License

Notifications You must be signed in to change notification settings

SolarLabRU/IvorySharp

Repository files navigation

IvorySharp

Build status Build status NuGet version

Платформа: NET Standard 2.0 |

На данный момент документация в Wiki неактуальна. Обновление в скором времени.

Библиотека предоставляет набор компонентов, реализующих некоторые возможности парадигмы АОП в языке C#. Если точнее, то библиотека позволяет вынести сквозную функциональность в отдельные компоненты и декларативно применять их к методам бизнес логики, используя атрибуты.

И зачем мне это ваше АОП ?

Как уже отмечалось, применений идей парадигмы позволяет избавиться от дублирующегося кода, разбросанного по всем слоям приложения. Примером может стать обработка ошибок. Допустим, есть ряд репозиториев, расположенных на уровне доступа к данным.

interface IUserRepository 
{
    int Add(User user);
    int Update(User user); 
}

В каждом методе репозитория находится одинаковая обработка ошибок вида

class UserRepository : IUserRepository 
{
  int Add(User user)
  {
    try {
      // Добавление в базу пользователя
    } catch (Exception e) {
      Logger.Error(e.Message, e);
      throw new WrappedException(e);
    }
  }
}

Рано или поздно обилие однообразных фрагментов кода приводит к появлению обобщенных обработчиков вида

class ExceptionHandlers {

  public static T HandleExceptions<T>(Func<T> action) 
  { ... }

}

И репозиторий преображается в следующий вид

class UserRepository : IUserRepository 
{
  int Add(User user)
  {
    return ExceptionHandlers.HandleExceptions(() => 
    { 
      // Добавление пользователя
    });
  }
}

Однако, это не решает проблему и так же нарушает принцип DRY, так как для отличающихся по сигнатуре делегатов придется писать свой дублирующийся фрагмент кода. При этом комбинирование такого рода обработчиков сводит читаемость и удобство поддержки функциональности на нет. В варианте с применением АОП репозиторий преобразуется следующим образом

interface IUserRepository 
{
    [HandleExceptionAspect]
    int Add(User user);
}

class UserRepository : IUserRepository {
  int Add(User user) {
    // Добавление пользователя
  }
}

[AttributeUsage(AttributeTargets.Method)]
class HandleExceptionAspect : MethodBoundaryAspect 
{
  public override void OnException(IInvocationPipeline pipeline)
  {
    var exception = pipeline.CurrentException;
    Logger.Error(exception.Message, exception);
    
    // Выбросит исключение, сохранив стек-трейс
    pipeline.Throw(new WrapperException(exception));
  }
}

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

И никто раньше такого не делал?

Делали само собой. Наиболее популярная библиотека реализующая АОП - это PostSharp. Его функциональность гораздо шире этой библиотеки, однако есть один минус - он платный. Есть и бесплатные альтернативы, например Fody и Mr.Advice, однако у них другой принцип работы. Данная библиотека выполняет динамическое проксирование вызовов через стандартные механизмы платформы (DispatchProxy), в то время как PostSharp и Fody выполняют инъекцию IL кода во время компиляции, что улучшает общую производительность, однако модифицирует код сборки. Наиболее близкое по принципу работы к представленной библиотеке - механизм динамического перехвата вызова в Castle.DynamicProxy. Для того чтобы лучше понять детали реализации библиотеки советую ознакомиться с этой статьей.

И в чем тогда преимущества этой библиотеки?

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

About

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

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published