.net 之设计模式的核心套路—AOP面向切面编程

POP面向过程编程

符合逻辑思维,线性的处理问题-----无法应付复杂的系统

OOP面向对象编程

万物皆对象,对象交互完成功能,功能叠加成模块,模块组成系统,去搭建复杂的大型软件系统
  砖块儿----墙---房间----大厦          砖块儿应该是稳定的,静态的
      类----功能点---模块----系统      
      类却是会变化的,增加日志/异常/权限/缓存/事务,只能修改类?
      GOF的23种设计模式,应对变化,核心套路是依赖抽象,细节就可以变化
      
 但是只能替换整个对象,但是没办法把一个类动态改变    

AOP面向切面编程

允许开发者动态的修改静态的OO模型,就像现实生活中对象在生命周期中会不断的改变自身。    
AOP是一种编程思想,是OOP思想的补充

正是因为能够动态的扩展功能,所以在程序设计时就可以有以下好处:
1 聚焦核心业务逻辑,权限/异常/日志/缓存/事务, 通用功能可以通过AOP方式添加,程序设计简单,
2 功能动态扩展;集中管理,代码复用;规范化;

实现AOP的多种方式:
a 静态实现--装饰器/代理模式
b 动态实现--Remoting/Castle(Emit)
c 静态织入--PostSharp(收费)--扩展编译工具,生成的加入额外代码
d 依赖注入容器的AOP扩展(开发)
e MVC的Filter--特性标记,然后该方法执行前/后就多了逻辑
  invoker调用中心--负责反射调用方法--检查特性--有则执行额外逻辑
 

整个项目URL:https://download.csdn.net/download/qq_33931256/11825909

今天,我们将通过.net使用Unity来进行依赖注入容器的AOP扩展开发示例

添加UnityNuGet包

整个项目结构如下

 

User.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace Model
{
    public class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Password { get; set; }
    }
}

IUserProcessor.cs

using System.Text;
using System.Threading.Tasks;
using Model;
namespace MyAOPTest.UnityWay
{
    public interface IUserProcessor
    {
        void RegUser(User user);
        User GetUser(User user);
    }
}

UnityConfigAOP.cs(Unity调用文件)

using Microsoft.Practices.Unity.Configuration;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Model;
using Unity;
using Unity.Interception.PolicyInjection.Policies;//InterceptionExtension

namespace MyAOPTest.UnityWay
{
    /// <summary>
    /// 
    /// 使用EntLib\PIAB Unity 实现动态代理
    /// 
    /// </summary>
    public class UnityConfigAOP
    {
        public static void Show()
        {
            User user = new User()
            {
                Name = "Eleven",
                Password = "1234567890123456789"
            };
            //配置UnityContainer
            IUnityContainer container = new UnityContainer();
            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
            //Unity.Config文件路径
            fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config");
            Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

            UnityConfigurationSection configSection = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
            //Unity节点
            configSection.Configure(container, "aopContainer");

            IUserProcessor processor = container.Resolve<IUserProcessor>();

            //实际调用的方法,通过IUserProcessor调用,但是调用的时候并没有直接执行这里面的内容,因为被动态代理了,所以会按照Unity.Config配置的节点顺序来执行
            processor.RegUser(user);
            processor.GetUser(user);
        }
    }
}

LogAfterBehavior.cs

//using Microsoft.Practices.Unity.InterceptionExtension;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.Interception.InterceptionBehaviors;
using Unity.Interception.PolicyInjection.Pipeline;

namespace MyAOPTest.UnityWay
{
    public class LogAfterBehavior : IInterceptionBehavior
    {
        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }
        //主要是这个Invoke方法
        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            Console.WriteLine("LogAfterBehavior");
            foreach (var item in input.Inputs)
            {
                Console.WriteLine(item.ToString());//反射获取更多信息
            }
            //这里表示执行Unity配置下一个节点的方法
            IMethodReturn methodReturn = getNext()(input, getNext);
            //执行完下一个节点的方法后,会回到这个地方
            Console.WriteLine("LogAfterBehavior" + methodReturn.ReturnValue);
            return methodReturn;
        }

        public bool WillExecute
        {
            get { return true; }
        }
    }
}

LogBeforeBehavior.cs

//using Microsoft.Practices.Unity.InterceptionExtension;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.Interception.InterceptionBehaviors;
using Unity.Interception.PolicyInjection.Pipeline;

namespace MyAOPTest.UnityWay
{
    /// <summary>
    /// 不需要特性
    /// </summary>
    public class LogBeforeBehavior : IInterceptionBehavior
    {
        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            Console.WriteLine("LogBeforeBehavior");
            foreach (var item in input.Inputs)
            {
                Console.WriteLine(item.ToString());//反射获取更多信息
            }
            //这里表示执行Unity配置下一个节点的方法
            return getNext().Invoke(input, getNext);
        }

        public bool WillExecute
        {
            get { return true; }
        }
    }
}

MonitorBehavior.cs

//using Microsoft.Practices.Unity.InterceptionExtension;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.Interception.InterceptionBehaviors;
using Unity.Interception.PolicyInjection.Pipeline;

namespace MyAOPTest.UnityWay
{
    /// <summary>
    /// 性能监控的AOP扩展
    /// </summary>
    public class MonitorBehavior : IInterceptionBehavior
    {
        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            Console.WriteLine(this.GetType().Name);
            //获取方法的名称
            string methodName = input.MethodBase.Name;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            var methodReturn = getNext().Invoke(input, getNext);//后续逻辑执行

            stopwatch.Stop();
            Console.WriteLine($"{this.GetType().Name}统计方法{methodName}执行耗时{stopwatch.ElapsedMilliseconds}ms");

            return methodReturn;
        }

        public bool WillExecute
        {
            get { return true; }
        }
    }
}

UserProcessor.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Model;
namespace MyAOPTest.UnityWay
{
    public class UserProcessor : IUserProcessor
    {
        public void RegUser(User user)
        {
            Console.WriteLine("用户已注册。");
            //throw new Exception("11");
        }

        public User GetUser(User user)
        {
            return user;
        }
    }
}

Program.cs(调用)


using MyAOPTest.UnityWay;
using System;

namespace MyAOPTest
{
    class Program
    {
        static void Main(string[] args)
        {
            UnityConfigAOP.Show();
        }
    }
}

Unity.Config(配置文件)

<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
    <!--Microsoft.Practices.Unity.Configuration.UnityConfigurationSection-->
  </configSections>
  <unity>
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
    <containers>
      <container name="aopContainer">
        <extension type="Interception"/>
        <!--注意程序集名和文件方法名必须一致-->
        <register type="MyAOPTest.UnityWay.IUserProcessor,MyAOPTest" mapTo="MyAOPTest.UnityWay.UserProcessor,MyAOPTest">
          <interceptor type="InterfaceInterceptor"/>
          <!--配置节点-->
          <interceptionBehavior type="MyAOPTest.UnityWay.MonitorBehavior, MyAOPTest"/>
          <interceptionBehavior type="MyAOPTest.UnityWay.LogBeforeBehavior, MyAOPTest"/>
          <interceptionBehavior type="MyAOPTest.UnityWay.LogAfterBehavior, MyAOPTest"/>
          
        </register>
      </container>
    </containers>
  </unity>
</configuration>

 

运行结果

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值