• 使用Microsoft Unity进行日志记录


    需要记录日志的地方包括:进入方法的时候,传参的时候,统计执行时间,方法返回参数的时候,退出语句块的时候,出现异常的时候,等等。先来体验不使用Micirosoft Unity进行日志记录。

     

        class Program
    
        {
    
            static void Main(string[] args)
    
            {
    
                Add(1, 2);
    
                Console.ReadKey();
    
            }
    
            private static int Add(int a, int b)
    
            {
    
                int result = 0;
    
                string temp = string.Empty;
    
                string returnValue = string.Empty;
    
                try
    
                {
    
                    //记录进入方法
    
                    Console.WriteLine("马上要执行方法了");
    
                    temp = string.Format("输入的参数为:a={0},b={1}", a, b);
    
                    Console.WriteLine(temp);
    
                    //统计方法执行时间
    
                    Stopwatch watch = new Stopwatch();
    
                    watch.Start();
    
                    result = a + b;
    
                    watch.Stop();
    
                    Console.WriteLine("程序执行时间为{0}", watch.Elapsed);
    
                    //记录返回值
    
                    returnValue = string.Format("返回结果是:{0}", result);
    
                    Console.WriteLine(returnValue);
    
                    //记录方法执行接收
    
                    Console.WriteLine("方法执行结束");
    
                }
    
                catch (Exception ex)
    
                {
    
                    //记录异常
    
                    Console.WriteLine(string.Format("异常信息是:{0},输入参数是:{1}", ex.ToString(), temp));
    
                    throw;
    
                }
    
                finally
    
                {
    
                    //记录异常处理
    
                    Console.WriteLine("异常已经被处理了");
    
                }
    
                return result;
    
            }
    
        }
    

    以上,还是存在一些问题:
    ○ 违反了"DRY"原则,如果还有其它方法,需要不断地写记录的逻辑
    ○ 对阅读代码造成影响
    ○ 耗时

     

    Microsoft Unity的出现就是解决以上问题。

    1


    ○ Proxy object or derived class是Unity拦截器,在执行方法前后进行拦截
    ○ Behaviors Pipeline是拦截行为管道,通过API注册
    ○ Target Object or Original class method是进行拦截的目标对象


    □ 引用Unity和Unity.Interception组件

    输入关键字Unity,通过NuGet安装Unity。
    输入关键字Unity.Interception,通过NuGet安装Unity Interception Extension。
    安装完后,相关组件包括:
    2

     

    □ 自定义拦截器

    自定义的拦截器必须实现IInterceptionBehavior接口。

     

        public class MyInterceptionBehavior : IInterceptionBehavior
    
        {
    
            //返回拦截行为所需要的接口
    
            public IEnumerable<Type> GetRequiredInterfaces()
    
            {
    
                return Type.EmptyTypes;
    
            }
    
            /// <summary>
    
            /// 使用本方法实施拦截行为
    
            /// </summary>
    
            /// <param name="input">目标方法的参数</param>
    
            /// <param name="getNext">在拦截管道中的拦截行为的委托</param>
    
            /// <returns>目标方法的返回值</returns>
    
            public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
    
            {
    
                Console.WriteLine("hello,方法马上开始执行~~");
    
                IMethodReturn msg = getNext()(input, getNext);
    
                Console.WriteLine("bye,方法执行完了");
    
                return msg;
    
            }
    
            //是否启用拦截
    
            public bool WillExecute
    
            {
    
                get { return true; }
    
            }
    
        }
    

     

    □ 定义一个计算的接口

     

        public interface ICalculator
    
        {
    
            int Add(int value1, int value2);
    
            int Subtract(int value1, int value2);
    
            int Multiply(int value1, int value2);
    
            int Divide(int value1, int value2);
    
        }

    □ 对接口实现

     

        public class Calculator : ICalculator
    
        {
    
            public int Add(int value1, int value2)
    
            {
    
                int res = value1 + value2;
    
                Console.WriteLine(res);
    
                return res;
    
            }
    
            public int Subtract(int value1, int value2)
    
            {
    
                int res = value1 - value2;
    
                return res;
    
            }
    
            public int Multiply(int value1, int value2)
    
            {
    
                int res = value1 * value2;
    
                return res;
    
            }
    
            public int Divide(int value1, int value2)
    
            {
    
                int res = value1 / value2;
    
                return res;
    
            }
    
        }
    

     

    □ 配置文件中配置Unity

     

    <configuration>
    
      <configSections>
    
        <section
    
           name="unity"
    
           type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, 
    
                   Microsoft.Practices.Unity.Configuration"/>
    
      </configSections>
    
      <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    
        <alias alias="ICalculator" type="MyLogging.ICalculator, MyLogging"/>
    
        <alias alias="Calculator" type="MyLogging.Calculator, MyLogging"/>
    
        <alias alias="MyBehavior" type="MyLogging.MyInterceptionBehavior, MyLogging" />
    
        <sectionExtension
    
           type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension,  
    
                 Microsoft.Practices.Unity.Interception.Configuration" />
    
        <container>
    
          <extension type="Interception"/>
    
          <register type="ICalculator" mapTo="Calculator">
    
            <interceptor type="InterfaceInterceptor" />
    
            <interceptionBehavior type="MyBehavior"/>
    
          </register>
    
        </container>
    
      </unity>
    
    </configuration>
    

    以上,
    ○ 通过<alias>节点为接口和类设置别名
    ○ type="MyLogging.ICalculator, MyLogging"中,逗号前面是类名,逗号后面是程序集名称

     

    □ 客户端调用

     

        using System;
    
        using System.Collections.Generic;
    
        using Microsoft.Practices.Unity;
    
        using Microsoft.Practices.Unity.InterceptionExtension;
    
        class Program
    
        {
    
            static void Main(string[] args)
    
            {
    
                //加载UnityContainer
    
                IUnityContainer container = new UnityContainer();
    
                container = Microsoft.Practices.Unity.Configuration.UnityContainerExtensions.LoadConfiguration(container);
    
                //解析出接口
    
                ICalculator calc = Microsoft.Practices.Unity.UnityContainerExtensions.Resolve<ICalculator>(container);
    
                //执行方法
    
                int res = calc.Add(1, 2);
    
                
    
                Console.ReadKey();
    
            }
    
        }
    

     

    3

     

    参考资料:
    http://www.lm-tech.it/Blog/post/2011/10/18/How-to-use-the-Unity-Interception-Extension.aspx

  • 相关阅读:
    CPU 后缀
    获取当前IP的接口
    win10 禁用自动更新
    C# 调用腾讯云接口获取视频基本信息
    SQL Server服务器角色和数据库角色描述
    C# 使用cmd
    C# 对DataTable的简单操作
    参考文档链接地址-个人比较推荐的
    类似input框内最右边添加图标,有清空功能
    CentOS-6.3安装Mysql-5.5.29[转]
  • 原文地址:https://www.cnblogs.com/darrenji/p/3963789.html
Copyright © 2020-2023  润新知