Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance 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

Contributors

AltStyle によって変換されたページ (->オリジナル) /