using MyAOP.UnityWay;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyAOP
{
/// <summary>
/// 1 AOP面向切面编程
/// 2 静态实现AOP
/// 3 动态实现AOP
/// 4 Unity、MVC中的AOP
///
/// AOP:面向切面编程 编程思想
/// OOP:一切皆对象,对象交互组成功能,功能叠加组成模块,模块叠加组成系统
/// 类--砖头 系统--房子
/// 类--细胞 系统--人
/// 面向对象是非常适合做大型系统
/// 应对需求变化扩展的时候,比较困难;
/// 面向对象是静态的:任何需求的细微变化,都可能导致比较大的影响
///
/// 设计模式:设计出灵活 可扩展 可重用 的架构 可以解决部分问题
/// 都在折腾抽象/类
/// 永远无法解决类的内部变化
///
/// AOP:面向切面编程 编程思想
/// 就是解决类的内部变化问题
/// 能做到让开发者动态的修改一个静态的面向对象模型,
/// 在不破坏封装的前提下,去增加各种功能:非业务逻辑,是一些公共逻辑
/// 是对OOP的有效补充
/// 有了AOP之后,OOP也变得简单了
///
/// Unity的AOP实现 依赖注入容器
/// </summary>
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("欢迎来到.Net高级班vip课程,今天学习面向切面AOP");
#region AOP show
#region 俩种静态实现AOP 代理,装饰器
Console.WriteLine("************DecoratorAOP***********");
DecoratorAOP.Show();
Console.WriteLine("************ProxyAOP***********");
ProxyAOP.Show();
#endregion
#region 三种动态实现AOP
Console.WriteLine("************RealProxyAOP***********");
RealProxyAOP.Show();
Console.WriteLine("************CastleProxyAOP***********");
CastleProxyAOP.Show();
Console.WriteLine("************UnityAOP***********");
UnityConfigAOP.Show();
#endregion
//UnityAOP.Show();
#endregion
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.Read();
}
}
}
静态实现AOP: 代理模式和装饰器模式
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyAOP
{
/// <summary>
/// 代理模式实现静态代理
/// AOP 在方法前后增加自定义的方法
/// </summary>
public class ProxyAOP
{
public static void Show()
{
User user = new User()
{
Name = "Eleven",
Password = "123123123123"
};
IUserProcessor processor = new UserProcessor();
processor.RegUser(user);
Console.WriteLine("***************");
processor = new ProxyUserProcessor();
processor.RegUser(user);
}
public interface IUserProcessor
{
void RegUser(User user);
}
public class UserProcessor : IUserProcessor
{
public void RegUser(User user)
{
Console.WriteLine("用户已注册。Name:{0},PassWord:{1}", user.Name, user.Password);
}
}
/// <summary>
/// 代理模式去提供一个AOP功能
/// </summary>
public class ProxyUserProcessor : IUserProcessor
{
private IUserProcessor _UserProcessor = new UserProcessor();
public void RegUser(User user)
{
BeforeProceed(user);
this._UserProcessor.RegUser(user);
AfterProceed(user);
}
/// <summary>
/// 业务逻辑之前
/// </summary>
/// <param name="user"></param>
private void BeforeProceed(User user)
{
Console.WriteLine("方法执行前");
}
/// <summary>
/// 业务逻辑之后
/// </summary>
/// <param name="user"></param>
private void AfterProceed(User user)
{
Console.WriteLine("方法执行后");
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyAOP
{
/// <summary>
/// 装饰器模式实现静态代理
/// AOP 在方法前后增加自定义的方法
/// </summary>
public class DecoratorAOP
{
public static void Show()
{
User user = new User()
{
Name = "Eleven",
Password = "123123123123"
};
IUserProcessor processor = new UserProcessor();
processor.RegUser(user);
Console.WriteLine("***************");
processor = new UserProcessorDecorator(processor);
processor.RegUser(user);
}
public interface IUserProcessor
{
void RegUser(User user);
}
public class UserProcessor : IUserProcessor
{
public void RegUser(User user)
{
Console.WriteLine("用户已注册。Name:{0},PassWord:{1}", user.Name, user.Password);
}
}
/// <summary>
/// 装饰器的模式去提供一个AOP功能
/// </summary>
public class UserProcessorDecorator : IUserProcessor
{
private IUserProcessor _UserProcessor { get; set; }
public UserProcessorDecorator(IUserProcessor userprocessor)
{
this._UserProcessor = userprocessor;
}
public void RegUser(User user)
{
BeforeProceed(user);
this._UserProcessor.RegUser(user);
AfterProceed(user);
}
/// <summary>
/// 业务逻辑之前
/// </summary>
/// <param name="user"></param>
private void BeforeProceed(User user)
{
Console.WriteLine("方法执行前");
}
/// <summary>
/// 业务逻辑之后
/// </summary>
/// <param name="user"></param>
private void AfterProceed(User user)
{
Console.WriteLine("方法执行后");
}
}
}
}
动态实现AOP .Net Remoting/RealProxy Castle\DynamicProxy EntLib\PIAB Unity
.Net Remoting/RealProxy
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.Text;
using System.Threading.Tasks;
namespace MyAOP
{
/// <summary>
/// 使用.Net Remoting/RealProxy 实现动态代理
/// 局限在业务类必须是继承自MarshalByRefObject类型
/// </summary>
public class RealProxyAOP
{
public static void Show()
{
User user = new User()
{
Name = "Eleven",
Password = "123456"
};
UserProcessor processor = new UserProcessor();
processor.RegUser(user);
Console.WriteLine("*********************");
UserProcessor userProcessor = TransparentProxy.Create<UserProcessor>();
userProcessor.RegUser(user);
}
/// <summary>
/// 真实代理
/// </summary>
/// <typeparam name="T"></typeparam>
public class MyRealProxy<T> : RealProxy
{
private T tTarget;
public MyRealProxy(T target)
: base(typeof(T))
{
this.tTarget = target;
}
public override IMessage Invoke(IMessage msg)
{
BeforeProceede(msg);
IMethodCallMessage callMessage = (IMethodCallMessage)msg;
object returnValue = callMessage.MethodBase.Invoke(this.tTarget, callMessage.Args);
AfterProceede(msg);
return new ReturnMessage(returnValue, new object[0], 0, null, callMessage);
}
public void BeforeProceede(IMessage msg)
{
Console.WriteLine("方法执行前可以加入的逻辑");
}
public void AfterProceede(IMessage msg)
{
Console.WriteLine("方法执行后可以加入的逻辑");
}
}
/// <summary>
/// 透明代理
/// </summary>
public static class TransparentProxy
{
public static T Create<T>()
{
T instance = Activator.CreateInstance<T>();
MyRealProxy<T> realProxy = new MyRealProxy<T>(instance);
T transparentProxy = (T)realProxy.GetTransparentProxy();
return transparentProxy;
}
}
public interface IUserProcessor
{
void RegUser(User user);
}
/// <summary>
/// 必须继承自MarshalByRefObject父类,否则无法生成
/// </summary>
public class UserProcessor : MarshalByRefObject, IUserProcessor
{
public void RegUser(User user)
{
Console.WriteLine("用户已注册。用户名称{0} Password{1}", user.Name, user.Password);
}
}
}
}
Castle\DynamicProxy
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Castle.DynamicProxy;//Castle.Core
namespace MyAOP
{
/// <summary>
/// 使用Castle\DynamicProxy 实现动态代理
/// 方法必须是虚方法
/// </summary>
public class CastleProxyAOP
{
public static void Show()
{
User user = new User()
{
Name = "Eleven",
Password = "123456"
};
ProxyGenerator generator = new ProxyGenerator();
MyInterceptor interceptor = new MyInterceptor();
UserProcessor userprocessor = generator.CreateClassProxy<UserProcessor>(interceptor);
userprocessor.RegUser(user);
}
public interface IUserProcessor
{
void RegUser(User user);
}
public class UserProcessor : IUserProcessor
{
/// <summary>
/// 必须带上virtual 否则无效~
/// </summary>
/// <param name="user"></param>
public virtual void RegUser(User user)
{
Console.WriteLine($"用户已注册。Name:{user.Name},PassWord:{user.Password}");
}
}
public class MyInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
PreProceed(invocation);
invocation.Proceed();
PostProceed(invocation);
}
public void PreProceed(IInvocation invocation)
{
Console.WriteLine("方法执行前");
}
public void PostProceed(IInvocation invocation)
{
Console.WriteLine("方法执行后");
}
}
}
}
EntLib\PIAB Unity
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;
using Unity.Interception.ContainerIntegration;
using Unity.Interception.Interceptors.InstanceInterceptors.InterfaceInterception;
using Unity.Interception.PolicyInjection.Pipeline;
using Unity.Interception.PolicyInjection.Policies;//InterceptionExtension
namespace MyAOP
{
/// <summary>
/// 使用EntLib\PIAB Unity 实现动态代理
///
/// </summary>
public class UnityAOP
{
public static void Show()
{
User user = new User()
{
Name = "Eleven",
Password = "1234567890123456789"
};
IUnityContainer container = new UnityContainer();//声明一个容器
container.RegisterType<IUserProcessor, UserProcessor>();//声明UnityContainer并注册IUserProcessor
//IUserProcessor processor = container.Resolve<IUserProcessor>();
//processor.RegUser(user);//调用
container.AddNewExtension<Interception>();
//container.RegisterType<IUserProcessor, UserProcessor>(new InterfaceInterceptor());
//IUserProcessor userprocessor = new UserProcessor();
IUserProcessor userprocessor = container.Resolve<IUserProcessor>();
Console.WriteLine("********************");
userprocessor.RegUser(user);//调用
userprocessor.GetUser(user);//调用
}
#region 特性对应的行为
public class UserHandler : ICallHandler
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
User user = input.Inputs[0] as User;
if (user.Password.Length < 10)
{
return input.CreateExceptionMethodReturn(new Exception("密码长度不能小于10位"));
}
Console.WriteLine("参数检测无误");
IMethodReturn methodReturn = getNext()(input, getNext); //getNext.Invoke().Invoke(input, getNext);
//Console.WriteLine("已完成操作");
return methodReturn;
}
}
public class LogHandler : ICallHandler
{
public int Order { get; set; }
/// <summary>
///
/// </summary>
/// <param name="input">方法调用的参数列表</param>
/// <param name="getNext"></param>
/// <returns></returns>
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
User user = input.Inputs[0] as User;
string message = $"RegUser:Username:{user.Name},Password:{user.Password}";
Console.WriteLine("日志已记录,Message:{0},Ctime:{1}", message, DateTime.Now);
return getNext()(input, getNext);
}
}
public class ExceptionHandler : ICallHandler
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
IMethodReturn methodReturn = getNext()(input, getNext);
if (methodReturn.Exception == null)
{
Console.WriteLine("无异常");
}
else
{
Console.WriteLine($"异常:{methodReturn.Exception.Message}");
}
return methodReturn;
}
}
public class AfterLogHandler : ICallHandler
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
IMethodReturn methodReturn = getNext()(input, getNext);
User user = input.Inputs[0] as User;
string message = string.Format("RegUser:Username:{0},Password:{1}", user.Name, user.Password);
Console.WriteLine("完成日志,Message:{0},Ctime:{1},计算结果{2}", message, DateTime.Now, methodReturn.ReturnValue);
return methodReturn;
}
}
#endregion 特性对应的行为
#region 特性
public class UserHandlerAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
ICallHandler handler = new UserHandler() { Order = this.Order };
return handler;
}
}
public class LogHandlerAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new LogHandler() { Order = this.Order };
}
}
public class ExceptionHandlerAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new ExceptionHandler() { Order = this.Order };
}
}
public class AfterLogHandlerAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new AfterLogHandler() { Order = this.Order };
}
}
#endregion 特性
#region 业务
[UserHandlerAttribute(Order = 1)]
//[ExceptionHandlerAttribute(Order = 3)]
//[LogHandlerAttribute(Order = 2)]
//[AfterLogHandlerAttribute(Order = 5)]
public interface IUserProcessor
{
void RegUser(User user);
User GetUser(User user);
}
public class UserProcessor : IUserProcessor
{
public void RegUser(User user)
{
Console.WriteLine("用户已注册。");
//throw new Exception("11");
}
public User GetUser(User user)
{
return user;
}
}
#endregion 业务
/*
TransparentProxyInterceptor:直接在类的方法上进行标记,但是这个类必须继承MarshalByRefObject...不建议用
VirtualMethod:直接在类的方法上进行标记,但这个方法必须是虚方法(就是方法要带virtual关键字)
InterfaceInterceptor:在接口的方法上进行标记,这样继承这个接口的类里实现这个接口方法的方法就能被拦截
*/
}
}
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
</configSections>
<unity>
<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
<containers>
<container name="aopContainer">
<extension type="Interception"/>
<register type="MyAOP.UnityWay.IUserProcessor,MyAOP" mapTo="MyAOP.UnityWay.UserProcessor,MyAOP">
<interceptor type="InterfaceInterceptor"/>
<interceptionBehavior type="MyAOP.UnityWay.ExceptionLoggingBehavior, MyAOP"/>
<interceptionBehavior type="MyAOP.UnityWay.CachingBehavior, MyAOP"/>
<interceptionBehavior type="MyAOP.UnityWay.LogBeforeBehavior, MyAOP"/>
<interceptionBehavior type="MyAOP.UnityWay.ParameterCheckBehavior, MyAOP"/>
<interceptionBehavior type="MyAOP.UnityWay.LogAfterBehavior, MyAOP"/>
</register>
<!--<register type="MyAOP.UnityWay.IUserProcessor,MyAOP" mapTo="MyAOP.UnityWay.UserProcessor,MyAOP">
<interceptor type="InterfaceInterceptor"/>
<interceptionBehavior type="MyAOP.UnityWay.ExceptionLoggingBehavior, MyAOP"/>
<interceptionBehavior type="MyAOP.UnityWay.CachingBehavior, MyAOP"/>
<interceptionBehavior type="MyAOP.UnityWay.LogBeforeBehavior, MyAOP"/>
<interceptionBehavior type="MyAOP.UnityWay.ParameterCheckBehavior, MyAOP"/>
<interceptionBehavior type="MyAOP.UnityWay.LogAfterBehavior, MyAOP"/>
</register>-->
</container>
</containers>
</unity>
</configuration>
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 MyAOP.UnityWay
{
/// <summary>
/// 不需要特性
/// </summary>
public class CachingBehavior : IInterceptionBehavior
{
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
private static Dictionary<string, object> CachingBehaviorDictionary = new Dictionary<string, object>();
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Console.WriteLine("CachingBehavior");
string key = $"{input.MethodBase.Name}_{Newtonsoft.Json.JsonConvert.SerializeObject(input.Inputs)}";
if (CachingBehaviorDictionary.ContainsKey(key))
{
return input.CreateMethodReturn(CachingBehaviorDictionary[key]);//直接返还 断路器 不再往下
}
else
{
IMethodReturn result = getNext().Invoke(input, getNext);
if (result.ReturnValue != null)
CachingBehaviorDictionary.Add(key, result.ReturnValue);
return result;
}
}
public bool WillExecute
{
get { return true; }
}
}
}
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 MyAOP.UnityWay
{
public class ExceptionLoggingBehavior : IInterceptionBehavior
{
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
IMethodReturn methodReturn = getNext()(input, getNext);
Console.WriteLine("ExceptionLoggingBehavior");
if (methodReturn.Exception == null)
{
Console.WriteLine("无异常");
}
else
{
Console.WriteLine($"异常:{methodReturn.Exception.Message}");
}
return methodReturn;
}
public bool WillExecute
{
get { return true; }
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyAOP.UnityWay
{
public interface IUserProcessor
{
void RegUser(User user);
User GetUser(User user);
}
}
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 MyAOP.UnityWay
{
public class LogAfterBehavior : IInterceptionBehavior
{
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
IMethodReturn methodReturn = getNext()(input, getNext);//执行后面的全部动作
Console.WriteLine("LogAfterBehavior");
Console.WriteLine(input.MethodBase.Name);
foreach (var item in input.Inputs)
{
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item));
//反射&序列化获取更多信息
}
Console.WriteLine("LogAfterBehavior" + methodReturn.ReturnValue);
return methodReturn;
}
public bool WillExecute
{
get { return true; }
}
}
}
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 MyAOP.UnityWay
{
/// <summary>
/// 不需要特性
/// </summary>
public class LogBeforeBehavior : IInterceptionBehavior
{
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Console.WriteLine("LogBeforeBehavior");
Console.WriteLine(input.MethodBase.Name);
foreach (var item in input.Inputs)
{
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item));
//反射&序列化获取更多信息
}
return getNext().Invoke(input, getNext);//
}
public bool WillExecute
{
get { return true; }
}
}
}
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 MyAOP.UnityWay
{
public class ParameterCheckBehavior : IInterceptionBehavior
{
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Console.WriteLine("ParameterCheckBehavior");
User user = input.Inputs[0] as User;//可以不写死类型,反射+特性完成数据有效性监测
if (user.Password.Length < 10)//可以过滤一下敏感词
{
//返回一个异常
return input.CreateExceptionMethodReturn(new Exception("密码长度不能小于10位"));
//throw new Exception("密码长度不能小于10位");
}
else
{
Console.WriteLine("参数检测无误");
return getNext().Invoke(input, getNext);
}
}
public bool WillExecute
{
get { return true; }
}
}
}
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 Unity;
using Unity.Interception.ContainerIntegration;
using Unity.Interception.Interceptors.InstanceInterceptors.InterfaceInterception;
using Unity.Interception.Interceptors.InstanceInterceptors.TransparentProxyInterception;
using Unity.Interception.PolicyInjection.Pipeline;
using Unity.Interception.PolicyInjection.Policies;//InterceptionExtension
namespace MyAOP.UnityWay
{
/// <summary>
/// 使用EntLib\PIAB Unity 实现动态代理
///
/// </summary>
public class UnityConfigAOP
{
public static void Show()
{
User user = new User()
{
Name = "Eleven",
Password = "12345678934534643"
};
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IUserProcessor, UserProcessor>();
IUserProcessor processor = container.Resolve<IUserProcessor>();
processor.RegUser(user);
}
{
//配置UnityContainer
IUnityContainer container = new UnityContainer();
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config");
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
UnityConfigurationSection configSection = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
configSection.Configure(container, "aopContainer");
IUserProcessor processor = container.Resolve<IUserProcessor>();
processor.RegUser(user);
User userNew1 = processor.GetUser(user);
User userNew2 = processor.GetUser(user);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyAOP.UnityWay
{
public class UserProcessor : IUserProcessor
{
public void RegUser(User user)
{
Console.WriteLine("用户已注册。");
//throw new Exception("11");
}
[Obsolete]
public User GetUser(User user)
{
return user;
}
}
}