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

运行效果:

 

posted on 2018-10-25 19:03  dz45693  阅读(3063)  评论(0编辑  收藏  举报

导航