需要有关设置Unity拦截的帮助

时间:2012-04-23 06:26:47

标签: unity-container enterprise-library enterprise-library-5 unity-interception

首先,我以前从未使用过Unity ...... 我想通过统一拦截向我们的项目介绍跟踪/记录 该项目相当大(约30000个文件)。目标是在每次尝试呼叫外部服务时跟踪性能/执行时间。遗憾的是,我不能使用任何其他图书馆 为了熟悉这个概念是如何工作的,我构建了一个我在MSDN上找到的小程序;但是我的log属性拦截仍然没有触发。我确信我缺少一些配置或/和初始化。 我感谢任何帮助。

这是我的主要计划:

namespace calc
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var t = new calc.Calculator.Calculator().Sub(5, 8);
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex.Message);
            }
        }
     }
}

这是计算器类:

namespace calc.Calculator
{
    public interface ICalculator
    {
        Int32 Sum(Int32 x, Int32 y);        
        Int32 Sub(Int32 x, Int32 y);
    }

    public class Calculator : ICalculator
    {        
        public Int32 Sum(Int32 x, Int32 y)
        {
            return x + y;
        }

        [NonNegativeCallHandler] // Intercept this method and run tracing on it
        public Int32 Sub(Int32 x, Int32 y)
        {
            return x - y;
        }
    }
}

这是我的CallHandler:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace calc.Tracing
{
    public class NonNegativeCallHandler : ICallHandler
    {
        public IMethodReturn Invoke(IMethodInvocation input,
                                GetNextHandlerDelegate getNext)
        {
            // Perform the operation
            var methodReturn = getNext().Invoke(input, getNext);

            // Method failed, go ahead
            if (methodReturn.Exception != null)
                return methodReturn;

            // If the result is negative, then throw an exception
            var result = (Int32)methodReturn.ReturnValue;

            if (result < 0)
            {
                var exception = new ArgumentException("...");
                var response = input.CreateExceptionMethodReturn(exception);

                // Return exception instead of original return value
                return response;
            }

            return methodReturn;
        }

        public int Order { get; set; }
    }
}

最后

* 以下是我的属性定义:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity.InterceptionExtension;
using Microsoft.Practices.Unity;

namespace calc.Tracing
{
     public class NonNegativeCallHandlerAttribute : HandlerAttribute
     {
         public override ICallHandler CreateHandler(IUnityContainer container)
         {
             return new NonNegativeCallHandler();
         }
     }
}

我还需要添加什么,以及(配置文件或内部构造函数等)... 为了使这段代码有效。

2 个答案:

答案 0 :(得分:0)

您的代码看起来来自this article by Dino Esposito。看起来您错过了有关配置的部分(使用流畅代码或通过配置添加策略的段落)。


<强>更新

你看过this page on MSDN吗?

答案 1 :(得分:0)

我找到了其中一个解决方案......我修改了我的程序类来注册容器.. 看起来根本不需要额外的配置。 这是修改后的程序:

namespace calc
{
class Program
{
    static void Main(string[] args)
    {
        ICalculator iCal;
        try
        {

            iCal = ConfigurePolicyInjectionWithUnity();

            var t = iCal.Sub(8, 5);
        }
        catch (Exception ex)
        {
            System.Console.WriteLine(ex.Message);
        }
    }

    static ICalculator ConfigurePolicyInjectionWithUnity()
    {
        IUnityContainer container = new UnityContainer();

        container.AddNewExtension<Interception>();
        container.RegisterType<ICalculator, 
                           calc.Calculator.Calculator>().Configure<Interception>()
            .SetInterceptorFor<ICalculator>(new InterfaceInterceptor());

            // resolve
            return container.Resolve<ICalculator>(); ;
        }
    }
}

现在,问题是...... 让我们说我有大约20种不同口味的计算器,每个类有大约3-4种方法可供追踪。每种方法都有 唯一签名 。所以3-4个方法x 20个类= ~80个方法,需要跟踪唯一的签名。 我所导致的是我不能用单一界面来描述所有这些方法......从上面的解决方案来看,至少在我的情况下,看起来每个类必须有一个接口才能实现拦截器。引入20-30个新接口只是为了记录,这看起来并不优雅。在这种情况下,使用拦截和只有一些帮助程序类来进行日志记录之间没有区别。我是对的吗?

有没有其他方法可以在不定义界面的情况下使用拦截?我只需要能够记录方法开始运行的时间和完成执行的时间。

任何帮助或想法都将不胜感激。