Unity,一个轻量级的可扩展的依赖注入容器,主要用于Aop(面向切面编程),在网上找了很多资料,看完还是一脸懵逼,写这篇文件主要是为了总结经验 按照自己的理解把unity的用法展示出来,方便自己和各位读者学习,话不多说,直接切入正题。
1.新建控制台工程
2.打开Vs NuGet 包管理工具,搜索unity,将下图红框内的所有包全部安装
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);
}
}
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; }
}
}
}
<?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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。