• AOP面向切面的编程使用Interceptor内置的容器进行属性注入


    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);
    }
    }
    }
  • 相关阅读:
    MYSQL学习中
    正则相关记录
    JS前台相关
    .net 时间格式
    SQL问题整理
    IIS 错误
    小型文件系统(littlefs)
    三极管NPN和PNP开关电路
    事件EVENT与waitforsingleobject的使用
    UpdateData(TRUE)与UpdateData(FALSE)的使用
  • 原文地址:https://www.cnblogs.com/1175429393wljblog/p/14266868.html
Copyright © 2020-2023  润新知