Fody
大约 2 分钟
Fody
介绍
- 项目位置:https://github.com/Fody/Home
- Fody 是一个Net程序集织入工具扩展
- Addins List:https://github.com/Fody/Home/blob/master/pages/addins.md
PropertyChanged.Fody
将引发PropertyChanged事件的代码注入实现INotifyPropertyChanged的类的属性设置器中。
缺点:编译器无法进行提示生成的代码
安装依赖包
Install-Package Fody Install-Package PropertyChanged.Fody
添加配置到 FodyWeavers.xml
<Weavers> <PropertyChanged/> </Weavers>
基本使用
// 实现 INotifyPropertyChanged
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string GivenNames { get; set; }
public string FamilyName { get; set; }
public string FullName => $"{GivenNames} {FamilyName}";
}
/* 部分生成的代码
string givenNames;
public string GivenNames
{
get => givenNames;
set
{
if (value != givenNames)
{
givenNames = value;
OnPropertyChanged(InternalEventArgsCache.GivenNames);
OnPropertyChanged(InternalEventArgsCache.FullName);
}
}
}
*/
version 4 新特性
如果实现了 INotifyPropertyChanged ,可以将类声明为分部类,将自动生成相关INotifyPropertyChanged 代码
public partial class Person : INotifyPropertyChanged { public string GivenNames { get; set; } public string FamilyName { get; set; } public string FullName => $"{GivenNames} {FamilyName}"; }
具有 [AddINotifyPropertyChangedInterface] 特性可以自动实现 INotifyPropertyChanged
[AddINotifyPropertyChangedInterfaceAttribute] public class MainWindowViewModel {}
属性特性
[DoNotNotify] // 阻止特定属性通知
[DependsOn] // 当参数属性修改是同时通知当前属性修改
[AlsoNotifyFor] // 当前属性修改时同时通知参数指定的属性修改
通知拦截
全局层面拦截使用静态方法
public static class PropertyChangedNotificationInterceptor { public static void Intercept( object target, Action onPropertyChangedAction, string propertyName) { onPropertyChangedAction(); } }
类层面拦截 重写 OnPropertyChanged() 方法
属性层面拦截 重写 On
<PropertyName
>Changed() 方法
过滤器
指定需要织入的类
// 只有 Fody.WpfDemo. 命名空间下的类进行属性通知织入 [assembly: PropertyChanged.FilterType("Fody.WpfDemo.")] namespace Fody.WpfDemo;
过滤器不会影响 INotifyPropertyChanged 相关事件代码生成
MethodBoundaryAspect.Fody
AOP 操作,可以修饰程序集、类和方法
主要功能:
- Hook into method start and end and exceptions
- 访问方法相关信息
- 可以使用过滤器
- 修改方法行为和参数
- 需要 [AllowChangingInputArgumentsAttribute] 修饰方法
- 不支持异步
依赖包
Install-Package MethodBoundaryAspect.Fody
创建配置文件 FodyWeavers.xml
使用方法
编写 Atribute
public sealed class TransactionScopeAttribute : OnMethodBoundaryAspect { public override void OnEntry(MethodExecutionArgs args) { /* 方法前调用 */ } public override void OnExit(MethodExecutionArgs args) { /* 方法后调用 */ } public override void OnException(MethodExecutionArgs args) { /* 异常处理 */ } }
应用切片
public class Sample { [TransactionScope] public void Method() { Debug.WriteLine("Do some database stuff isolated in surrounding transaction"); } }
异步方法
执行顺序:
当第一次在主线程上调用 MethodAsync 时,调用 OnEntry() 方法
执行 MethodAsync 中 await 之前的代码
返回主线程,调用 OnExit() 方法
MethodAsync 中的异步代码执行完成后继续执行其中的同步代码
OnException() 将在 MethodAsync 抛出异常时执行
异步特点:
- OnExit() 始终会执行
- OnException() 可能在 OnExit() 之后一段时间执行
【实现方式 1 】使 OnExit() 在 MethodAsync 执行完之后才执行
public sealed class LogAttribute : OnMethodBoundaryAspect { public override void OnEntry(MethodExecutionArgs args) { WriteLine("On entry"); } public override void OnExit(MethodExecutionArgs args) { // 等待异步任务执行完成 if (args.ReturnValue is Task t) t.ContinueWith(task => WriteLine("On exit")); } public override void OnException(MethodExecutionArgs args) { WriteLine("On exception"); } }