Нужна помощь в настройке перехвата Unity

Во-первых, я никогда раньше не использовал Unity... Я хочу внедрить Tracing/Logging в наш проект через перехват единства.
Проект довольно большой (~30000 файлов). Цель состоит в том, чтобы отслеживать производительность/период выполнения каждый раз, когда мы пытаемся вызвать внешний сервис. К сожалению, я не могу использовать никакую другую библиотеку.
Чтобы ознакомиться с тем, как эта концепция будет работать, я создал небольшую программу, которую нашел в MSDN; однако мой перехват с атрибутом журнала по-прежнему не срабатывает. Я уверен, что мне не хватает какой-то конфигурации или/и инициализации. Я ценю любую помощь.

Вот моя основная программа:

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();
         }
     }
}

Что еще мне нужно добавить и где (файл конфигурации или внутри конструктора и т. д.), чтобы этот код работал.


person user1112906    schedule 23.04.2012    source источник


Ответы (2)


Ваш код выглядит так, как будто он взят из этой статьи Дино Эспозито. Похоже, вы пропустили раздел о настройке (параграфы «Использование Fluent Code» или «Добавление политик через настройку»).


Обновить

Вы просматривали эту страницу в MSDN< /а>?

person Sebastian Weber    schedule 23.04.2012
comment
Да, как я уже говорил ранее, я нашел небольшую программу в Интернете, и я думаю, что мне не хватает части конфигурации, чтобы эта программа работала правильно, однако в статье, которую вы разместили, не указано, как следует применять конфигурацию в случае, если атрибуты используются. На самом деле автор приводит два примера: через Fluent API, где он говорит, что подход можно применять, если атрибуты не нужны: Если вам не нравятся атрибуты, вы можете выразить ту же логику через Fluent API. - person user1112906; 25.04.2012
comment
2. Добавление политик через конфигурацию. Я пытался использовать это, но безуспешно. Именно поэтому я прошу о помощи. Любой образец конфигурации, который будет работать с предоставленным кодом, будет присвоен :-) - person user1112906; 25.04.2012

Я нашел одно из решений... Я модифицировал свой класс программы для регистрации контейнера. И похоже, что никакой дополнительной настройки не требуется вообще. Вот модифицированная программа:

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 новых интерфейсов только для того, чтобы иметь логирование. В этом случае нет никакой разницы между использованием перехвата и просто наличием некоторого вспомогательного класса для ведения журнала. Я прав?

Есть ли другой способ использовать перехват без определения интерфейса? Все, что мне нужно, это иметь возможность регистрировать время начала выполнения методов и время завершения их выполнения.

Любая помощь или идеи будут оценены.

person user1112906    schedule 26.04.2012
comment
Я потерялся. Вопрос начался с общих измерений времени трассировки/регистрации/выполнения. Код, который вы разместили, реализует проверку границ возвращаемого значения. Какие требования предъявляются к перехватчикам? - person ErnieL; 26.04.2012