Skip to content

Castle 实现 AOP

更新: 2023-12-13 16:20:13   字数: 0 字   时长: 0 分钟

由 Castle.DynamicProxy 提供动态代理功能

GitHub

实现 IInterceptor 接口

C#
// Program.cs
// Author: xulai

using AOP;
using Service;
using Castle.DynamicProxy;

ProxyGenerator proxy = new();
IUser user = new User();
CustomInterceptor customInterceptor = new();
var userProxy = proxy.CreateInterfaceProxyWithTarget(user, customInterceptor);
userProxy.Create("Processing");

namespace Service
{
    public class User : IUser
    {
        public void Create(string name)
        {
            Console.WriteLine($"This is {name}.");
        }
    }
    public interface IUser
    {
        void Create(string name);
    }
}

namespace AOP
{
    public class CustomInterceptor : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            BeforeProcess();
            invocation.Proceed();
            AfterProcess();
        }
        private static void BeforeProcess()
        {
            Console.WriteLine($"This is BegoreProcess.");
        }
        private static void AfterProcess()
        {
            Console.WriteLine($"This is AfterProcess.");
        }
    }
}

继承 StandardInterceptor 类

C#
// Program.cs
// Author: xulai

using AOP;
using Service;
using Filter;
using Castle.DynamicProxy;
using System.Reflection;

ProxyGenerator proxy = new();
IUser user = new User();
CustomInterceptor customInterceptor = new();
var userProxy = proxy.CreateInterfaceProxyWithTarget(user, customInterceptor);
userProxy.Create("Processing");

namespace Service
{
    public class User : IUser
    {
        public void Create(string name)
        {
            Console.WriteLine($"This is {name}.");
        }
    }
    public interface IUser
    {
        [CheckIP, CheckLogin, BeforeAction, AfterAction]
        void Create(string name);
    }
}

namespace AOP
{
    public class CustomInterceptor : StandardInterceptor
    {
        protected override void PreProceed(IInvocation invocation)
        {
            var method = invocation.Method;
            Action<IInvocation> action = base.PreProceed;
            var attributes = method
                .GetCustomAttributes<BaseAopAttribute>(true)
                .OrderByDescending(x => x.Order)
                .ToArray();
            foreach (var attribute in attributes)
            {
                action = attribute.AopAction(invocation, action);
            }
            action.Invoke(invocation);
        }
        protected override void PerformProceed(IInvocation invocation)
        {
            if (invocation.Method.IsDefined(typeof(BeforeActionAttribute), true))
            {
                Console.WriteLine($"This is BegoreProcess.");
            }
            base.PerformProceed(invocation);
        }
        protected override void PostProceed(IInvocation invocation)
        {
            if (invocation.Method.IsDefined(typeof(AfterActionAttribute), true))
            {
                Console.WriteLine($"This is AfterProcess.");
            }
            base.PostProceed(invocation);
        }
    }
}

namespace Filter
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    public abstract class BaseAopAttribute : Attribute
    {
        public abstract int Order { get; set; }
        public abstract Action<IInvocation> AopAction(IInvocation invocation, Action<IInvocation> action);
    }

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    public class BeforeActionAttribute : Attribute { }

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    public class AfterActionAttribute : Attribute { }

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    public class CheckIPAttribute : BaseAopAttribute
    {
        public override int Order { get; set; } = 1;
        public override Action<IInvocation> AopAction(IInvocation invocation, Action<IInvocation> action)
        {
            return (invocation) =>
            {
                Console.WriteLine("This is CheckIP.");
                action.Invoke(invocation);
            };
        }
    }

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    public class CheckLoginAttribute : BaseAopAttribute
    {
        public override int Order { get; set; } = 2;
        public override Action<IInvocation> AopAction(IInvocation invocation, Action<IInvocation> action)
        {
            return (invocation) =>
            {
                Console.WriteLine("This is CheckLogin.");
                action.Invoke(invocation);
            };
        }
    }
}
你觉得这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度