Castle 实现 AOP
更新: 2023-12-13 16:20:13 字数: 0 字 时长: 0 分钟
由 Castle.DynamicProxy 提供动态代理功能
实现 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);
};
}
}
}