当前位置:
首页 > Python基础教程 >
-
C# AOP学习笔记(2)
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
IMethodReturn methodReturn = getNext()(input, getNext);
if (methodReturn.Exception == null)
{
Console.WriteLine("ExceptionHandler:没有异常");
}
else
{
Console.WriteLine($"ExceptionHandler:出现异常:{methodReturn.Exception.Message}");
}
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 = string.Format($"Name:{user.Name} Password:{user.Password}");
Console.WriteLine($"LogHandler:日志已记录。Message:{message}");
IMethodReturn methodReturn = getNext()(input, getNext);
return methodReturn;
}
}
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("UserHandler:密码长度不能小于10位"));
}
//getNext()(input, getNext):委托后的委托,即多重委托。
IMethodReturn methodReturn = getNext()(input, getNext);
return methodReturn;
}
}
public class AfterLogHandler : ICallHandler
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
IMethodReturn methodReturn = getNext()(input, getNext);
Console.WriteLine($"AfterLogHandler:方法执行结果--{methodReturn.ReturnValue}");
Console.WriteLine("AfterLogHandler:方法执行后");
return methodReturn;
}
}
#endregion 特性对应的行为
/// <summary>
/// 运行测试
/// </summary>
public static void Show()
{
User user = new User() { Name = "Hello", Password = "HelloWorld" };
IUnityContainer container = new UnityContainer(); //声明一个容器
container.AddNewExtension<Interception>()
.RegisterType<IUserProcessor, UserProcessor>(new Interceptor<TransparentProxyInterceptor>(), new InterceptionBehavior<PolicyInjectionBehavior>()); //显式拦截
IUserProcessor processor = container.Resolve<IUserProcessor>();
processor.RegUser(user); //调用
}
}
3)调用:
static void Main(string[] args) { #region 使用EntLib\PIAB Unity实现动态代理(非配置) UnityAOP.Show(); Console.Read(); #endregion }
4)运行结果如下:
3.2.4、使用EntLib\PIAB Unity实现AOP(带配置)
1)继续在NuGet中安装Unity.Configuration、Unity.Interception.Configuration及Newtonsoft.Json。
2)分别建立以下类:
/// <summary> /// 用户类 /// </summary> public class User { public int Id { get; set; } public string Name { get; set; } public string Password { get; set; } }
/// <summary> /// 用户注册接口 /// </summary> public interface IUserProcessor { void RegUser(User user); }
/// <summary> /// 用户注册接口实现类 /// </summary> public class UserProcessor : IUserProcessor { public void RegUser(User user) { Console.WriteLine($"用户注册成功。Name:{user.Name} Password:{user.Password}"); } }
/// <summary> /// 使用EntLib\PIAB Unity实现动态代理(带配置) /// </summary> public class UnityConfigAOP { public static void Show() { User user = new User() { Name = "Hello", Password = "HelloWorld" }; //配置UnityContainer IUnityContainer container = new UnityContainer(); ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap { ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + @"UnityConfigAOP\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); } }
/// <summary> /// 不需要特性 /// </summary> public class ExceptionBehavior : IInterceptionBehavior { public bool WillExecute { get { return true; } } public IEnumerable<Type> GetRequiredInterfaces() { return Type.EmptyTypes; } public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) { IMethodReturn methodReturn = getNext()(input, getNext); Console.WriteLine("ExceptionBehavior"); if (methodReturn.Exception == null) { Console.WriteLine("无异常"); } else { Console.WriteLine($"异常:{methodReturn.Exception.Message}"); } return methodReturn; } }
/// <summary> /// 不需要特性 /// </summary> public class CachingBehavior : IInterceptionBehavior { private static Dictionary<string, object> CachingBehaviorDictionary = new Dictionary<string, object>(); public bool WillExecute { get { return true; } } public IEnumerable<Type> GetRequiredInterfaces() { return Type.EmptyTypes; } 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; } } }
/// <summary> /// 不需要特性 /// </summary> public class PermissionBehavior : IInterceptionBehavior { public bool WillExecute { get { return true; } } public IEnumerable<Type> GetRequiredInterfaces() { return Type.EmptyTypes; } public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) { Console.WriteLine("PermissionBehavior"); Console.WriteLine(input.MethodBase.Name); foreach (var item in input.Inputs) { Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); //反射&序列化获取更多信息 } return getNext().Invoke(input, getNext); } }
/// <summary> /// 不需要特性 /// </summary> public class ParameterCheckBehavior : IInterceptionBehavior { public bool WillExecute { get { return true; } } public IEnumerable<Type> GetRequiredInterfaces() { return Type.EmptyTypes; } public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) { User user = input.Inputs[0] as User; //可以不写死类型,反射+特性完成数据有效性监测。 Console.WriteLine("ParameterCheckBehavior"); if (user.Password.Length < 10) //可以过滤一下敏感词 { return input.CreateExceptionMethodReturn(new Exception("密码长度不能小于10位")); } else { return getNext().Invoke(input, getNext); } } }
/// <summary> /// 不需要特性 /// </summary> public class LogBehavior : IInterceptionBehavior { public bool WillExecute { get { return true; } } public IEnumerable<Type> GetRequiredInterfaces() { return Type.EmptyTypes; } public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) { IMethodReturn methodReturn = getNext()(input, getNext); //执行后面的全部动作 Console.WriteLine("LogBehavior"); Console.WriteLine(input.MethodBase.Name); foreach (var item in input.Inputs) { Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item)); //反射&序列化获取更多信息 } return methodReturn; } }
3)新建一个配置文件Unity.Config(本例代码是在UnityConfigAOP文件夹下),在其属性的复制到输出目录项下选择始终复制。
<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"/> <!--注册匹配规则:前面是完整类型名称,后面是所在的dll名称。--> <register type="LinkTo.Test.ConsoleAop.UnityConfigAOP.IUserProcessor,LinkTo.Test.ConsoleAop" mapTo="LinkTo.Test.ConsoleAop.UnityConfigAOP.UserProcessor,LinkTo.Test.ConsoleAop"> <interceptor type="InterfaceInterceptor"/> <!--拦截顺序为由上而下;配置会全部执行,除非遇到断路器等;建议异常处理包在最外层,即在最上面。--> <interceptionBehavior type="LinkTo.Test.ConsoleAop.UnityConfigAOP.ExceptionBehavior, LinkTo.Test.ConsoleAop"/> <interceptionBehavior type="LinkTo.Test.ConsoleAop.UnityConfigAOP.CachingBehavior, LinkTo.Test.ConsoleAop"/> <interceptionBehavior type="LinkTo.Test.ConsoleAop.UnityConfigAOP.PermissionBehavior, LinkTo.Test.ConsoleAop"/> <interceptionBehavior type="LinkTo.Test.ConsoleAop.UnityConfigAOP.ParameterCheckBehavior, LinkTo.Test.ConsoleAop"/> <interceptionBehavior type="LinkTo.Test.ConsoleAop.UnityConfigAOP.LogBehavior, LinkTo.Test.ConsoleAop"/> </register> </container> </containers> </unity> </configuration>
4)调用:
static void Main(string[] args) { #region 使用EntLib\PIAB Unity实现动态代理(带配置) UnityConfigAOP.UnityConfigAOP.Show(); Console.Read(); #endregion }
5)运行结果如下:
3.3、IL编织方式
IL编织方式,可以使用PostSharp框架来做,但是由于Postsharp从2.0版本开始收费,此处不再作说明,有兴趣的话可以百度一下。
参考自:
https://www.cnblogs.com/landeanfen/p/4782370.html
https://www.cnblogs.com/artech/archive/2011/12/01/autointerception.html
E神公开课代码