AOP - C# Fody中的方法和属性拦截
很久很久以前用过postsharp来做AOP, 大家知道的,现在那东东需要付费,于是尝试了一下Fody,但是发现Fody跟新太快了,所以大家在安装fody的时候尽力安装老的版本:packages.config
<?xml version="1.0" encoding="utf-8"?> <packages> <package id="Cauldron.Interception.Fody" version="2.0.27" targetFramework="net461" /> <package id="Costura.Fody" version="1.6.2" targetFramework="net461" developmentDependency="true" /> <package id="Fody" version="2.5.0" targetFramework="net461" developmentDependency="true" /> </packages>
创建一个方法拦截的demo如下:
using Cauldron.Interception; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace FodyTest { [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public class LoggerAttribute : Attribute, IMethodInterceptor { private string methodName; public void OnEnter(Type declaringType, object instance, MethodBase methodbase, object[] values) { this.methodName = methodbase.Name; this.AppendToFile($"Enter -> {declaringType.Name} {methodbase.Name} {string.Join(" ", values)}"); } public void OnException(Exception e) => this.AppendToFile($"Exception -> {e.Message}"); public void OnExit() => this.AppendToFile($"Exit -> {this.methodName}"); private void AppendToFile(string line) { File.AppendAllLines("log.txt", new string[] { line }); Console.WriteLine(">> " + line); } } }
属性拦截如下:
using Cauldron.Interception; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FodyTest { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public sealed class OnPropertySetAttribute : Attribute, IPropertySetterInterceptor { [AssignMethod("{CtorArgument:0}")] public Action<string, object> onSetMethod = null; public OnPropertySetAttribute(string methodName) { } public void OnException(Exception e) { } public void OnExit() { } public bool OnSet(PropertyInterceptionInfo propertyInterceptionInfo, object oldValue, object newValue) { this.onSetMethod?.Invoke(propertyInterceptionInfo.PropertyName, newValue); return false; } } }
创建FodyWeavers.xml:
<?xml version="1.0" encoding="utf-8"?> <Weavers> <Cauldron.Interception /> <Costura /> </Weavers>
调用code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FodyTest { [OnPropertySet(nameof(ExecuteMe))] public class PropertySetterTestClass { public int BookId { get; set; } public string BookName { get; set; } private void ExecuteMe(string propertyName, object newValue) => Console.WriteLine($"The property '{propertyName}' has a new value: '{newValue ?? ""}'"); } [Logger] internal class Program { private static int Add(int a, int b) => a + b; private static void Main(string[] args) { Console.WriteLine(Add(5, 20)); var sampleClass = new PropertySetterTestClass { BookName = "50 shades of C#", BookId = 23432 }; Console.ReadLine(); } } }
运行效果:
windows技术爱好者
标签:
C#
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构