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技术爱好者