运用Unity结合PolicyInjection实现拦截器[结合操作日志实例]

上一篇文章我们通过Unity自身Unity.InterceptionExtension.IInterceptionBehavior实现一个有系统关异常日志记录;解决代码中到处充满的异常记录的代码;

本文则是通过Unity.InterceptionExtension.ICallHandler实现一个操作日志记录功能;在相应操作方法上通过特性Attribute把操作日志进行统一处理;若想了解Unity依赖注入及AOP功能可以查看先前其它文章;

运用Unity结合PolicyInjection实现拦截器[结合操作日志实例]

 

1:首先我们在公共助手层Command层新建OperateLogCallHandler类及OperateLogAttribute类

其中类OperateLogCallHandler继承自ICallHandler,并且我们定义的属性(MessageInfo,ShowThrow),此处我们只是简单的显示出操作内容信息,若实际项目可以对下面进行简单修改便可,比如写入日志、数据库等;代码result.Exception == null则表示执行代码没有出现异常才逻辑写入

using Microsoft.Practices.Unity.InterceptionExtension;



namespace Command

{

    public class OperateLogCallHandler:ICallHandler

    {

        public string _messageInfo { set; get; }



        public bool _showThrow { get; set; }

        

        private int _order = 0;



        public OperateLogCallHandler(string MessageInfo, bool ShowThrow)

        {

            this._messageInfo = MessageInfo;

            this._showThrow = ShowThrow;

        }



        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)

        {

            if (input == null) throw new ArgumentNullException("input");

            if (getNext == null) throw new ArgumentNullException("getNext");



            var result = getNext()(input, getNext);

            if (result.Exception == null)

            {

                //进行逻辑代码编写  比如把操作内容写入数据库

                Console.WriteLine("操作的内容为:" + _messageInfo);

            }

            if (_showThrow) result.Exception = null;

            return result;

        }



        public int Order

        {

            get

            {

                return _order;

            }

            set

            {

                _order = value;

            }

        }

    }

}

而类OperateLogAttribute则继承自HandlerAttribute,并且我们设定此特性只能作用于方法上;

using Microsoft.Practices.Unity.InterceptionExtension;

namespace Command

{

    [AttributeUsage(AttributeTargets.Method)]

    public class OperateLogAttribute : HandlerAttribute

    {

        public string messageInfo { get; set; }



        public bool showThrow { get; set; }



        public OperateLogAttribute()

        {

 

        }



        public OperateLogAttribute(string MessagInfo, bool ShowThrow)

        {

            this.messageInfo = MessagInfo;

            this.showThrow = ShowThrow;

        }



        public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container)

        {

            OperateLogCallHandler handler = new OperateLogCallHandler(this.messageInfo, this.showThrow);

            handler.Order = this.Order;

            return handler;

        }

    }

}

2:公共层里还有一个助手类UnityContainerHelp,用于读取加载配置

using Microsoft.Practices.Unity;

using Microsoft.Practices.Unity.Configuration;

using Microsoft.Practices.Unity.InterceptionExtension;

using Microsoft.Practices.Unity.InterceptionExtension.Configuration;

using System.Configuration;

using System.Reflection;



namespace Command

{

    public class UnityContainerHelp

    {

        private IUnityContainer container;

        public UnityContainerHelp()

        {

            container = new UnityContainer();

            UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

            container.LoadConfiguration(section, "FirstClass");

        }



        public T GetServer<T>()

        {

            return container.Resolve<T>();

        }



        /// <summary>

        /// 

        /// </summary>

        /// <typeparam name="T"></typeparam>

        /// <param name="ConfigName">配置文件中指定的文字</param>

        /// <returns></returns>

        public T GetServer<T>(string ConfigName)

        {

            return container.Resolve<T>(ConfigName);

        }



        /// <summary>

        /// 返回构结函数带参数

        /// </summary>

        /// <typeparam name="T">依赖对象</typeparam>

        /// <param name="parameterList">参数集合(参数名,参数值)</param>

        /// <returns></returns>

        public T GetServer<T>(Dictionary<string, object> parameterList)

        {

            var list = new ParameterOverrides();

            foreach (KeyValuePair<string, object> item in parameterList)

            {

                list.Add(item.Key, item.Value);

            }

            return container.Resolve<T>(list);

        }

        /// <summary>

        /// 返回构结函数带参数

        /// </summary>

        /// <typeparam name="T">依赖对象</typeparam>

        /// <param name="ConfigName">配置文件中指定的文字(没写会报异常)</param>

        /// <param name="parameterList">参数集合(参数名,参数值)</param>

        /// <returns></returns>

        public T GetServer<T>(string ConfigName,Dictionary<string,object> parameterList)

        {

            var list = new ParameterOverrides();

            foreach (KeyValuePair<string, object> item in parameterList) 

            {

                list.Add(item.Key, item.Value);

            }

            return container.Resolve<T>(ConfigName,list);

        }

    }

}

3:接着在接口层相应的方法上使用我们刚才创建的特性,注意必需引用Microsoft.Practices.Unity.InterceptionExtension.dll;若则特性将会找不到

using Microsoft.Practices.Unity.InterceptionExtension;

using Command;

namespace IAopBLL

{

    public interface IUser

    {

        [OperateLog(Order = 10, messageInfo = "增加用户", showThrow = true)]

        void CreateUser();



        [OperateLog(Order = 10, messageInfo = "编辑用户", showThrow = true)]

        void UpdateUser();

    }

}

4:在BLL层里实现上面的接口,在方法里面我们就不进行任何操作

using IAopDAL;

using IAopBLL;

using Command;

namespace AopBLL

{

    public class UserBLL:IUser

    {

        public void CreateUser()

        {

            //逻辑代码,此处为了简单就省略不写

        }



        public void UpdateUser()

        {

            //逻辑代码,此处为了简单就省略不写

        }

    }

}

5:下面为主程序调用代码,这里我们简单运用到Unity依赖注入代码

using IAopBLL;

using Command;

namespace AopUnity

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.WriteLine("-----------------------------------");

            IUser bllProperty = new UnityContainerHelp().GetServer<IUser>("UserBllAop");

            bllProperty.CreateUser();

            bllProperty.UpdateUser();

            Console.WriteLine("-----------------------------------");

        }

    }

}

配置文件的内容如下:其中有两个比较要注意的地方(a处 name="UserBllAop" 主程序里有调用 b处 <policyInjection/>拦载器才会起作用)

<?xml version="1.0"?>

<configuration>

  <configSections>

    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>

  </configSections>

  <unity xmlns="http://schemas.microsoft.com/practces/2010/unity">

    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/>

    <container name="FirstClass">

      <extension type="Interception"/>

      <register type="IAopBLL.IUser,IAopBLL" mapTo="AopBLL.UserBLL,AopBLL" name="UserBllAop">

        <interceptor type="InterfaceInterceptor" />

        <policyInjection/>

      </register>

    </container>

  </unity> 

<startup>

<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>

</startup>

</configuration>

6:运行效果:

运用Unity结合PolicyInjection实现拦截器[结合操作日志实例]

从图中我们不难发现Aop已起到作用,在操作没有异常的情况下我们成功获得操作内容;当然其它Aop比如权限判断,事务处理等都可以用此种办法;

你可能感兴趣的:(inject)