zoukankan      html  css  js  c++  java
  • 运用Unity结合PolicyInjection实现拦截器[结合操作日志实例]

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

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

    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:运行效果:

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

  • 相关阅读:
    CF 336494 C. Meme Problem
    MySql备份
    MySQL索引背后的数据结构及算法原理
    show profile 开启权限
    示例数据库
    索引使用策略及优化
    shiro权限登录案例
    Swagger技术
    Shiro框架
    shiro授权管理
  • 原文地址:https://www.cnblogs.com/wujy/p/3326316.html
Copyright © 2011-2022 走看看