Unity(C# AOP) 使用教程(配置文件方式)
2021/5/8 22:55:27
本文主要是介绍Unity(C# AOP) 使用教程(配置文件方式),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Unity,一个轻量级的可扩展的依赖注入容器,主要用于Aop(面向切面编程),在网上找了很多资料,看完还是一脸懵逼,写这篇文件主要是为了总结经验 按照自己的理解把unity的用法展示出来,方便自己和各位读者学习,话不多说,直接切入正题。
1.新建控制台工程
2.打开Vs NuGet 包管理工具,搜索unity,将下图红框内的所有包全部安装
3.创建实体类,代码如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Aborlen.Model { /// <summary> /// 用户信息 /// </summary> public class UserInfo { /// <summary> /// 用户Id /// </summary> public int Id { get; set; } /// <summary> /// 用户名 /// </summary> public string Name { get; set; } /// <summary> /// 用户密码 /// </summary> public string Password { get; set; } } }
4.创建接口
using Aborlen.Model; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Aborlen.Interface { /// <summary> /// 用户操作接口 /// </summary> public interface IUserProcessor { /// <summary> /// 注册用户 /// </summary> /// <param name="user"></param> void RegUser(UserInfo user); /// <summary> /// 获取用户 /// </summary> /// <param name="user"></param> /// <returns></returns> UserInfo GetUser(UserInfo user); } }
5.创建用户注册业务逻辑
using Aborlen.Interface; using Aborlen.Model; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Aborlen.Bll { /// <summary> /// 用户业务 /// </summary> public class UserProcessor : IUserProcessor { /// <summary> /// 注册用户 /// </summary> /// <param name="user"></param> public void RegUser(UserInfo user) { Console.WriteLine($"用户:{user.Name}已注册。"); } /// <summary> /// 获取用户 /// </summary> /// <param name="user"></param> /// <returns></returns> public UserInfo GetUser(UserInfo user) { return user; } } }
6.创建Aop扩展方法
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 Aborlen.AopExtension { /// <summary> /// 扩展Aop方法(模拟插入日志) /// </summary> public class LogBeforeBehavior : IInterceptionBehavior { public IEnumerable<Type> GetRequiredInterfaces() { return Type.EmptyTypes; } public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) { #region 此处编写需要添加的业务逻辑(写日志逻辑) Console.WriteLine("*************************日志****************************");//模拟写日志 #endregion return getNext().Invoke(input, getNext);// 执行实例方法(必须调用),如果先调用实例方法,再执行扩展操作,则需要先调用getNext().Invoke(input, getNext) 方法 。 } public bool WillExecute { get { return true; } } } }
7.创建配置文件(Unity.config)
<?xml version="1.0" encoding="utf-8" ?> <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="Aborlen.Interface.IUserProcessor,Aborlen.Interface" mapTo="Aborlen.Bll.UserProcessor,Aborlen.Bll"> <interceptor type="InterfaceInterceptor"/> <!--扩展的方法名称--> <interceptionBehavior type="Aborlen.AopExtension.LogBeforeBehavior, Aborlen.AopExtension"/> </register> </container> </containers> </unity> </configuration>
8.Unity调用
using Aborlen.Interface; using Aborlen.Model; 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; namespace MyAop { class Program { static void Main(string[] args) { UserInfo user = new UserInfo() { Id=1, Name = "Aborlen", Password = "888888888888888899999999" }; //创建容器 IUnityContainer container = new UnityContainer(); ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(); fileMap.ExeConfigFilename = Path.Combine(new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory).Parent.Parent.FullName + "\\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); UserInfo userNew1 = processor.GetUser(user); Console.WriteLine("********************结束***************************"); Console.ReadLine(); } } }
运行结果如下:
写日志成功。
注意事项:
扩展
1.方法结果缓存
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 Aborlen.AopExtension { /// <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; } } } }
2.方法异常处理
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 Aborlen.AopExtension { /// <summary> /// 方法异常处理 /// </summary> 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; } } } }
3.方法执行后操作
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 Aborlen.AopExtension { /// <summary> /// 方法执行后操作 /// </summary> 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; } } } }
4.方法参数检查(用于敏感词过滤,参数长度检查等)
using Aborlen.Model; 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 Aborlen.AopExtension { /// <summary> /// 参数检查(敏感词过滤等场景) /// </summary> public class ParameterCheckBehavior : IInterceptionBehavior { public IEnumerable<Type> GetRequiredInterfaces() { return Type.EmptyTypes; } public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) { Console.WriteLine("ParameterCheckBehavior"); UserInfo user = input.Inputs[0] as UserInfo; if (user.Password.Length < 10) { //返回一个异常 return input.CreateExceptionMethodReturn(new Exception("密码长度不能小于10位")); } else { Console.WriteLine("参数检测无误"); return getNext().Invoke(input, getNext); } } public bool WillExecute { get { return true; } } } }
5.扩展后的配置文件
<?xml version="1.0" encoding="utf-8" ?> <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="Aborlen.Interface.IUserProcessor,Aborlen.Interface" mapTo="Aborlen.Bll.UserProcessor,Aborlen.Bll"> <interceptor type="InterfaceInterceptor"/> <!--扩展的方法名称--> <!--方法异常处理--> <interceptionBehavior type="Aborlen.AopExtension.ExceptionLoggingBehavior, Aborlen.AopExtension"/> <!-- 执行缓存方法--> <interceptionBehavior type="Aborlen.AopExtension.CachingBehavior, Aborlen.AopExtension"/> <!--方法执行前相关操作--> <interceptionBehavior type="Aborlen.AopExtension.LogBeforeBehavior, Aborlen.AopExtension"/> <!--参数检查--> <interceptionBehavior type="Aborlen.AopExtension.ParameterCheckBehavior, Aborlen.AopExtension"/> <!--方法执行后操作--> <interceptionBehavior type="Aborlen.AopExtension.LogAfterBehavior, Aborlen.AopExtension"/> </register> </container> </containers> </unity> </configuration>
最后给出源代码,方便读者测试
百度网盘:https://pan.baidu.com/s/1UAZ935ktOu2YbEm9eUx8oA
提取码:u2td
这篇关于Unity(C# AOP) 使用教程(配置文件方式)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-12-06使用Microsoft.Extensions.AI在.NET中生成嵌入向量
- 2024-11-18微软研究:RAG系统的四个层次提升理解与回答能力
- 2024-11-15C#中怎么从PEM格式的证书中提取公钥?-icode9专业技术文章分享
- 2024-11-14云架构设计——如何用diagrams.net绘制专业的AWS架构图?
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#