AOP面向切面的编程使用Interceptor内置的容器进行属性注入
1. NuGet程序包管理添加Castle Core,主要用于拦截器的使用,Startup ConfigureServices中添加如下内容
public void ConfigureServices(IServiceCollection services) { #region Controller控制器中的属性注入 //把控制器作为服务注册,然后使用它内置的ioc来替换原来的控制器的创建器,这样就可以使用IOC来依赖注入和控制反转创建对应的控制器 services.AddControllersWithViews().AddControllersAsServices(); services.Replace(ServiceDescriptor.Transient<IControllerActivator, CustomServiceBaseControllerActivator>()); services.AddTransient<ITestA, TestA>(); services.AddTransient<ITestB, TestB>(); #endregion }
2. 自定义拦截器和aop切面编程的拦截器的扩展放方法
using Castle.DynamicProxy; using System; namespace WebAppTest.Extensions { /// <summary> /// 自定义拦截器 /// </summary> public class CustomInterceptor : StandardInterceptor { protected override void PerformProceed(IInvocation invocation) { Console.WriteLine($"方法{invocation.Method.Name}执行前。。。。"); base.PerformProceed(invocation); Console.WriteLine($"方法{invocation.Method.Name}执行后。。。。"); } protected override void PreProceed(IInvocation invocation) { base.PreProceed(invocation); } protected override void PostProceed(IInvocation invocation) { base.PostProceed(invocation); } } /// <summary> /// aop切面编程的拦截器的扩展放方法 /// </summary> public static class AOPExtension { public static object AOP(this object obj, Type interfaceType) { ProxyGenerator proxyGenerator = new ProxyGenerator(); CustomInterceptor customInterceptor = new CustomInterceptor(); return proxyGenerator.CreateInterfaceProxyWithTarget(interfaceType, obj, customInterceptor); } } }
3. 控制器Controller中,使用拦截器,接口服务标记拦截器需要拦截的特性
using WebAppTest.CustomAttrributes; namespace WebAppTest.Services { public interface ITestA {
//接口服务标记拦截器需要拦截的特性 [LogBeforeAttribute] [LogAfterAttribute] void Show(); } } //控制器Controller中,使用拦截器 public IActionResult Index() { //_testA.Show(); _testB.Show(); ((ITestA)_testA.AOP(typeof(ITestA))).Show(); return View(); }
4. 自定义特性标记
using Castle.DynamicProxy; using System; namespace WebAppTest.CustomAttrributes { #region 自定义的控制器创建对象,以便使用ioc创建控制器,Controller控制器属性注入和Controller控制器方法注入 其实IOC就是一个字典Dictionary /// <summary> /// 属性的特性标记,主要用于标记属性 /// </summary> [AttributeUsage(AttributeTargets.Property)] public class CustomPropertyAttribute : Attribute { } /// <summary> /// 方法的特性标记,主要用于标记方法 /// </summary> [AttributeUsage(AttributeTargets.Method)] public class CustomMethodAttribute : Attribute { } #endregion #region 拦截器特性111 ///// <summary> ///// 标记方法拦截前 ///// </summary> //public class LogBeforeAttribute : Attribute //{ // public void Do() { // Console.WriteLine("LogBeforeAttribute执行---前"); // } //} ///// <summary> ///// 标记方法拦截中 ///// </summary> //public class LogMonitorAttribute : Attribute //{ //} ///// <summary> ///// 标记方法拦截后 ///// </summary> //public class LogAfterAttribute : Attribute //{ // public void Do() // { // Console.WriteLine("LogAfterAttribute执行---后"); // } //} #endregion #region 拦截器特性抽象 public abstract class AbstractAttribute : Attribute { public abstract Action Do(IInvocation invocation, Action action); } /// <summary> /// 标记方法拦截前 /// </summary> public class LogBeforeAttribute : AbstractAttribute { public override Action Do(IInvocation invocation, Action action) { return () => { action.Invoke(); //添加需要处理的操作 Console.WriteLine($"LogBeforeAttribute执行---前,{invocation.Method.Name}"); }; } } /// <summary> /// 标记方法拦截中 /// </summary> public class LogMonitorAttribute : AbstractAttribute { public override Action Do(IInvocation invocation, Action action) { return () => { Console.WriteLine($"LogMonitorAttribute执行---中,{invocation.Method.Name}"); //添加需要处理的操作 action.Invoke(); //添加需要处理的操作 Console.WriteLine($"LogMonitorAttribute执行---中,{invocation.Method.Name}"); }; } } /// <summary> /// 标记方法拦截后 /// </summary> public class LogAfterAttribute : AbstractAttribute { public override Action Do(IInvocation invocation, Action action) { return () => { Console.WriteLine($"LogAfterAttribute执行---后,{invocation.Method.Name}"); //添加需要处理的操作 action.Invoke(); }; } } #endregion }
5. 使用不同的需求,例如在某个方法前拦截,方法后来拦截,方法中拦截
using Castle.DynamicProxy; using System; using System.Reflection; using WebAppTest.CustomAttrributes; namespace WebAppTest.Extensions { #region 自定义拦截器-可以拦截所有接口方法,都一样不能更具需要特殊定制,如:方法前拦截,方法后来拦截,方法中拦截,没有办法做到 ///// <summary> ///// 自定义拦截器-可以拦截所有接口方法,都一样不能更具需要特殊定制,如:方法前拦截,方法后来拦截,方法中拦截,没有办法做到 ///// </summary> //public class CustomInterceptor : StandardInterceptor //{ // protected override void PerformProceed(IInvocation invocation) // { // Console.WriteLine($"方法{invocation.Method.Name}执行前。。。。"); // base.PerformProceed(invocation); // Console.WriteLine($"方法{invocation.Method.Name}执行后。。。。"); // } // protected override void PreProceed(IInvocation invocation) // { // base.PreProceed(invocation); // } // protected override void PostProceed(IInvocation invocation) // { // base.PostProceed(invocation); // } //} #endregion #region 方法前拦截,方法后来拦截,方法中拦截 public class CustomInterceptor : StandardInterceptor { protected override void PerformProceed(IInvocation invocation) { Console.WriteLine($"方法{invocation.Method.Name}执行前。。。。"); Action action = () => base.PerformProceed(invocation); var customAtts = invocation.Method.GetCustomAttributes<AbstractAttribute>(); foreach (var customAtt in customAtts) { action = customAtt.Do(invocation, action); } action.Invoke(); Console.WriteLine($"方法{invocation.Method.Name}执行后。。。。"); } //protected override void PreProceed(IInvocation invocation) //{ // var customAtt = invocation.Method.GetCustomAttribute<LogBeforeAttribute>(); // customAtt.Do(); // base.PreProceed(invocation); //} //protected override void PostProceed(IInvocation invocation) //{ // var customAtt = invocation.Method.GetCustomAttribute<LogBeforeAttribute>(); // customAtt.Do(); // base.PostProceed(invocation); //} } #endregion /// <summary> /// aop切面编程的拦截器的扩展放方法 /// </summary> public static class AOPExtension { public static object AOP(this object obj, Type interfaceType) { ProxyGenerator proxyGenerator = new ProxyGenerator(); CustomInterceptor customInterceptor = new CustomInterceptor(); return proxyGenerator.CreateInterfaceProxyWithTarget(interfaceType, obj, customInterceptor); } } }