AOP - C# Fody中的方法和屬性攔截

好久好久之前用過postsharp來作AOP, 你們知道的,如今那東東須要付費,因而嘗試了一下Fody,可是發現Fody跟新太快了,因此你們在安裝fody的時候盡力安裝老的版本:packages.configpost

<?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以下:this

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

屬性攔截以下:spa

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:3d

<?xml version="1.0" encoding="utf-8"?>
<Weavers>
  <Cauldron.Interception />
  <Costura />
</Weavers>

調用code: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();
        }
    }
}

運行效果:xml

相關文章
相關標籤/搜索