(精华)2020年8月13日 C#基础知识点 AOP实现原理(装饰器模式,代理模式,.Net Remoting真实代理,Castle动态代理,Unity动态代理)
(精华)2020年8月13日 C#基础知识点 AOP实现原理(装饰器模式,代理模式,.Net Remoting真实代理,Castle动态代理,Unity动态代理)
一:装饰器实现AOP
/// <summary>
/// 装饰器模式实现静态代理
/// AOP 在方法前后增加自定义的方法
/// </summary>
public class DecoratorAOP
{<!-- -->
public static void Show()
{<!-- -->
User user = new User()
{<!-- -->
Name = "看看看看",
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
/// <summary>
/// 代理模式实现静态代理
/// AOP 在方法前后增加自定义的方法
/// </summary>
public class ProxyAOP
{<!-- -->
public static void Show()
{<!-- -->
User user = new User()
{<!-- -->
Name = "哈哈哈哈",
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("方法执行后");
}
}
}
三:使用.Net Remoting/RealProxy 真实代理实现AOP
/// <summary>
/// 使用.Net Remoting/RealProxy 实现动态代理
/// 局限在业务类必须是继承自MarshalByRefObject类型
/// </summary>
public class RealProxyAOP
{<!-- -->
public static void Show()
{<!-- -->
User user = new User()
{<!-- -->
Name = "换换换",
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);//Log try-catch
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 动态代理实现AOP
/// <summary>
/// 使用Castle\DynamicProxy 实现动态代理
/// 方法必须是虚方法
/// </summary>
public class CastleProxyAOP
{<!-- -->
public static void Show()
{<!-- -->
User user = new User()
{<!-- -->
Name = "啦啦啦",
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 实现动态代理
public class UnityAOP
{<!-- -->
public static void Show()
{<!-- -->
User user = new User()
{<!-- -->
Name = "Unity",
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>()
.Configure<Interception>()
.SetInterceptorFor<IUserProcessor>(new InterfaceInterceptor());
//映射类型
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);
return methodReturn;
}
}
public class LogHandler : ICallHandler
{<!-- -->
public int Order {<!-- --> get; set; }
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("用户已注册。");
}
public User GetUser(User user)
{<!-- -->
return user;
}
}
#endregion 业务
}
五:使用EntLib\PIAB Unity 读取配置文件方式实现动态代理
第一步:使用Unity需要nuget引入6个包
- Unity1. Unity.Abstractions1. Unity.Configuration1. Unity.Container1. Unity.Interception1. Unity.Interception.Configuration 第二步:固定写法
public class UnityConfigAOP
{<!-- -->
public static void Show()
{<!-- -->
User user = new User()
{<!-- -->
Name = "配置文件方式实现",
Password = "1234567890123456789"
};
//创建容器
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中
UnityConfigurationSection configSection = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
configSection.Configure(container, "aopContainer");
//使用
IUserProcessor processor = container.Resolve<IUserProcessor>();
processor.RegUser(user);
processor.GetUser(user);
}
}
三:配置文件
<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="MyAOP.UnityWay.IUserProcessor,MyAOP" mapTo="MyAOP.UnityWay.UserProcessor,MyAOP">
<interceptor type="InterfaceInterceptor"/>
<interceptionBehavior type="MyAOP.UnityWay.MoniterBehavior, MyAOP"/>
<interceptionBehavior type="MyAOP.UnityWay.LogBeforeBehavior, MyAOP"/>
<interceptionBehavior type="MyAOP.UnityWay.ParameterCheckBehavior, MyAOP"/>
<interceptionBehavior type="MyAOP.UnityWay.CachingBehavior, MyAOP"/>
<interceptionBehavior type="MyAOP.UnityWay.ExceptionLoggingBehavior, MyAOP"/>
<interceptionBehavior type="MyAOP.UnityWay.LogAfterBehavior, MyAOP"/>
</register>
</container>
</containers>
</unity>
</configuration>
四:aop切面拦截器的类
/// <summary>
/// 不需要特性
/// </summary>
public class MoniterBehavior : IInterceptionBehavior
{<!-- -->
public IEnumerable<Type> GetRequiredInterfaces()
{<!-- -->
return Type.EmptyTypes;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{<!-- -->
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
// 可以在这儿添加方法之前的逻辑
var query = getNext().Invoke(input, getNext);
stopwatch.Stop();
Console.WriteLine($"执行耗时:{stopwatch.ElapsedMilliseconds} ms");
return query;
}
public bool WillExecute
{<!-- -->
get {<!-- --> return true; }
}
}
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());//反射获取更多信息
}
var query = getNext().Invoke(input, getNext);
//下一个节点的方法已经执行完毕
//在这里计入方法执行后的逻辑
return query;
//现在是21:53 大家开始提问 && 休息 21:57 开始答疑!期间老师不说话
}
public bool WillExecute
{<!-- -->
get {<!-- --> return true; }
}
}
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)
{<!-- -->
//throw new Exception();
return input.CreateExceptionMethodReturn(new Exception("密码长度不能小于10位"));
}
else
{<!-- -->
Console.WriteLine("参数检测无误");
return getNext().Invoke(input, getNext);
}
}
public bool WillExecute
{<!-- -->
get {<!-- --> return true; }
}
}
public class CachingBehavior : IInterceptionBehavior
{<!-- -->
public IEnumerable<Type> GetRequiredInterfaces()
{<!-- -->
return Type.EmptyTypes;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{<!-- -->
Console.WriteLine("CachingBehavior");
//input.Target.GetType().GetCustomAttributes()
if (input.MethodBase.Name.Equals("GetUser"))
return input.CreateMethodReturn(new User() {<!-- --> Id = 234, Name = "Richard" });
return getNext().Invoke(input, getNext);
}
public bool WillExecute
{<!-- -->
get {<!-- --> return true; }
}
}
public class ExceptionLoggingBehavior : IInterceptionBehavior
{<!-- -->
public IEnumerable<Type> GetRequiredInterfaces()
{<!-- -->
return Type.EmptyTypes;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{<!-- -->
Console.WriteLine("ExceptionLoggingBehavior");
IMethodReturn methodReturn = getNext()(input, getNext);
if (methodReturn.Exception == null)
{<!-- -->
Console.WriteLine("无异常");
}
else
{<!-- -->
Console.WriteLine($"异常:{methodReturn.Exception.Message}");
}
return methodReturn;
}
public bool WillExecute
{<!-- -->
get {<!-- --> return true; }
}
}
public class LogAfterBehavior : IInterceptionBehavior
{<!-- -->
public IEnumerable<Type> GetRequiredInterfaces()
{<!-- -->
return Type.EmptyTypes;
}
//一切正常的 刷个1
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{<!-- -->
Console.WriteLine("LogAfterBehavior");
foreach (var item in input.Inputs)
{<!-- -->
Console.WriteLine(item.ToString());//反射获取更多信息
}
IMethodReturn methodReturn = getNext()(input, getNext);
Console.WriteLine("LogAfterBehavior" + methodReturn.ReturnValue);
return methodReturn;
}
public bool WillExecute
{<!-- -->
get {<!-- --> return true; }
}
}