fody - aop

26
Fody Халявная реализация АОП для .NET

Upload: viktor-love

Post on 08-Jul-2015

478 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Fody - AOP

FodyХалявная реализация АОП для .NET

Page 2: Fody - AOP

АОП

Аспектно-ориентированное программирование – парадима программирования, основанная на понятии сквозной функциональности, т.е. служебной функциональности.

Если реализовывать сквозную функциональность вместе с бизнес-логикой, то код становится полнейшей гадостью.

Page 3: Fody - AOP

Примеры сквозной функциольности:

•Логирование

•Обработка исключений

•Проверка прав доступа

•Проверка правильности аргументов

•Кеширование

Page 4: Fody - AOP

Fody

Fody – это фреймворк для внедрения сквозной функциональности во время компиляции.

Fody позволяет манипулировать IL кодом сборки.

Page 5: Fody - AOP

Fody

В действительности Fody – это не совсем АОП.Цель у них одна, но у Fody теоретических возможностей больше, а практических меньше.Поскольку Fody сам по себе нам не интересен, мы будем рассматривать его плагины.

Page 6: Fody - AOP

Fody / лицензия

Fody распространяется под MIT License

Разрешено:

• Коммерческое использование

• Изменение

• Распространение

Не разрешено:

• Жаловаться на качество

Необходимо:

• Включать копирайт(если вы собираетесь расширять Fody)

Page 7: Fody - AOP

Fody / PropertyChanged

Облегчает жизнь при написании классов, реализующих INotifyPropertyChanging.

Нету необходимости дергать event PropertyChanged вручную -> снижается количество кода на объявление свойств

Page 8: Fody - AOP

Fody / PropertyChanged / Атрибуты

[ImplementPropertyChanged]

Вешается на класс и все свойства автоматически начинают уведомлять о изменениях самих себя.

Все классы-наследники тоже начинают ввести себя подобным образом.

Те свойства, которые уже уведомляли о изменениях не будут уведомлять дважды.

Page 9: Fody - AOP

Написанный программистом код

public int Age { get; set; }

private int age;

public int Age

{

get

{

return this.age;

}

set

{

this.age = value;

this.RaisePropertyChanged();

}

}

=>

Скомпилированный код

Page 10: Fody - AOP

Fody сам отслеживает дерево завимостей свойств.

Т.е. если меняется свойство FirstName и от него зависит свойство FullName, то происходит автоматическое уведомление о изменении обоих свойств.

public string FirstName { get; set; }

public string LastName { get; set; }

public string FullName { get { return this.FirstName + this.LastName; } }

Page 11: Fody - AOP

Fody / PropertyChanged / Атрибуты

[DoNotNotify]

Вешается на свойство для того, чтобы Fody не пытался уведомлять о его изменениях.

Типичное применение – для свойств, которые содержат какую-то страшную кастомную логику

Page 12: Fody - AOP

Fody / PropertyChanged / Атрибуты

[AlsoNotifyFor]

Вешается на свойство для того, чтобы уведомить о изменениях другого свойства.

[AlsoNotifyFor(“FullName”)]

public string FirstName { get; set; }

public string FullName { get; set; }

Page 13: Fody - AOP

Fody / PropertyChanged / Атрибуты

[DependsOn]Вешается на свойство для того, чтобы происходили уведомления о его изменении, при изменении других.

public string FirstName { get; set; }

[DependsOn(“FirstName”)]

public string FullName { get; set; }

Page 14: Fody - AOP

On{PropertyName}Changed()

Если в классе есть есть метод с сигнатурой подобной

void On{PropertyName}Changed()

, то при изменении свойства PropertyName будет вызываться этот метод.

Page 15: Fody - AOP

OnPropertyChanged()

Если в классе есть есть метод с сигнатурой

void OnPropertyChanged(string name, object before,object after)

, то при изменении свойств будет вызываться этот метод.

Page 16: Fody - AOP

Fody / Ionad

Позволяет заменять статические вызовы одних методов статическими вызовами других.[StaticReplacement(typeof(DateTime))]public static class DateTimeSubstitute{

public static IDateTime Current { get; set; }

public static DateTime Now { get { return Current.Now; } }}

public void SomeMethod(){

var time = DateTime.Now;// ...

}

public void SomeMethod(){

var time = DateTimeSubstitute.Now;// ...

}

=>

Page 17: Fody - AOP

Fody / NullGuard

Автоматический выброс исключений, если входное значение или выходное значение равно null.

Контроль осуществляется с помощью двух атрибутов:

[NullGuard] – вешается на сборку или класс

[AllowNull] – вешается на аргумент, возвращаемое значение или целое свойство

Page 18: Fody - AOP

Fody / NullGuard

Конструктор [NullGuard] принимает перечисление ValidationFlags:

• Properties = 1,

• Arguments = 2,

• OutValues = 4,

• ReturnValues = 8,

• NonPublic = 16,

• Methods = Arguments | OutValues | ReturnValues,

• AllPublicArguments = Properties | Arguments,

• AllPublic = Properties | Methods,

• All = AllPublic | NonPublic

Page 19: Fody - AOP

Fody / NullGuard / Примеры использования:abstract void Method([AllowNull] string arg);

[return: AllowNull]

abstract string MethodAllowsNullReturnValue() { return null; }

[AllowNull]

public string NullProperty { get; set; }

public string NullPropertyOnSet { get; [param: AllowNull] set; }

Page 20: Fody - AOP

Fody / NullGuard / Замечания

Не рекомендуется его использовать на UI-шной сборке.

Более адекватным видится использование в DataAccess-слое и вью-моделях.

Page 21: Fody - AOP

Fody / Equals

Занимается генерацией методов Equals(), GetHashCode(), операторов сравнения и заставляет класс реализовывать интерфейс IEquatable<T>.

Page 22: Fody - AOP

Fody / Equals / Средства контроля

Атрибут [Equals] – вешается на класс, который должен будет поддерживать сравнение.

При создании можно указать следующие параметры:

• bool DoNotAddEqualityOperators

• bool DoNotAddGetHashCode

• bool DoNotAddEquals

• TypeCheck (перечисление, которое содержит возможности проверки типа (тот же тип; тот же или наследник)

Page 23: Fody - AOP

Fody / Equals / Средства контроля

Атрибут [IgnoreDuringEquals] – вешается на свойство, которое нужно исключить из сравнения.

Атрибут [CustomEqualsInternal] – вешается на метод для кастомной части сравнения. Этот метод должен возвращать булево значение.

Page 24: Fody - AOP

Fody / Equals / Средства контроля

Недоработка авторов плагина: [IgnoreDuringEquals] исключает свойство из генерации хеш-кода и нет возможности описать метод кастомного обсчета хеш-кода

Page 25: Fody - AOP

Fody / MethodCache

Кеширование возвращаемых значений метода.

Что надо сделать:

1. В классе оставить свойство вида

private ICache Cache { get; set; }

2. В это свойство положить нашу реализацию кеша.

3. Навешать атрибут [Cache] на нужный метод.

Page 26: Fody - AOP

Fody / MethodCache

Небольшой фейл разработчика. Ключ для кеширования метода, принимающего два параметра выглядит так:

string.Format("Namespace.Class.Add_{0}_{1}", new object[] { a, b });

Т.е. параметры a и b должны реализовывать хороший ToString() метод