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) 使用教程(配置文件方式)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程