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"); } }
