Простой инжектор, функция не перехватывается?

Я пытаюсь перехватить мои вызовы на моем контроллере, но по какой-то причине они не перехватываются.

Я в основном пытаюсь заставить этот пример работать: http://simpleinjector.readthedocs.org/en/latest/InterceptionExtensions.html

Здесь также есть другая информация в разделе перехвата: http://simpleinjector.readthedocs.org/en/latest/advanced.html

У меня такое ощущение, что я неправильно настраиваю Контейнер. Может ли кто-нибудь показать мне, как мне нужно изменить мой основной, чтобы увидеть "Intercepted!!!" после выполнения вызовов на контроллере? Кроме того, может ли кто-нибудь сказать мне, была ли установка контейнера неправильной, и если да, объясните мои ошибки.

Код:

static void Main()
{
    Console.WriteLine("Start");    

    RedisController2 redisController = new RedisController2();    

    Container _container = new Container();
    _container.InterceptWith<MonitoringInterceptor>(type => type == typeof(IRedisController2));
    _container.RegisterSingle<MonitoringInterceptor>();    

    redisController.PrintSomething();
    redisController.PrintOther();    

    Console.WriteLine("Press any key to exit.");
    Console.ReadKey();
}

internal class MonitoringInterceptor : IInterceptor
{    

    public MonitoringInterceptor()
    {    

    }    

    public void Intercept(IInvocation invocation)
    {
        invocation.Proceed();    

        //var decoratedType = invocation.InvocationTarget.GetType();    

        Console.Write("Intercepted!!!");
        Console.ReadKey();
    }
}

person Tony    schedule 29.12.2014    source источник


Ответы (2)


Проблема связана с тем, что Контейнер не создает Контроллер и, следовательно, не может перехватывать сделанные ему вызовы. Попробуй это:

Console.WriteLine("Start");    

Container _container = new Container();
_container.Register<IRedisController2, RedisController2>(); // 1
_container.InterceptWith<MonitoringInterceptor>(type => 
    type == typeof(IRedisController2));
_container.RegisterSingle<MonitoringInterceptor>();    

IRedisController2 redisController =
    _container.GetInstance<IRedisController2>(); // 2, 3

redisController.PrintSomething();
redisController.PrintOther();    

Console.WriteLine("Press any key to exit.");
Console.ReadKey();

Обратите внимание, что у меня есть:

  1. добавлен код для регистрации Контроллера
  2. добавлен код для запроса экземпляра Контроллера из Контейнера
  3. изменил создаваемый тип с RedisController2 на IRedisController2 (поскольку IRedisController2 - это то, что было настроено для перехвата)
person qujck    schedule 29.12.2014

Предполагая, что SimpleInjector работает так же, как 90% всех контейнеров IOC, он использует RealProxy под крышками * (с учетом подписи это наиболее вероятно, хотя полностью противоречит духу SimpleInjector).

Примечание. Фрагменты кода расширений перехвата используют класс .NET System.Runtime.Remoting.Proxies.RealProxy для создания прокси-серверов перехвата. RealProxy позволяет только прокси-интерфейсы. [источник]

RealProxy работает с интерфейсами по понятной причине (если задуматься над этим некоторое время). Даже если он может работать с базовым классом, этот базовый класс должен объявить свой метод как virtual, чтобы ваш код работал.

Измените свой код, чтобы использовать интерфейсы при вызове RedisController2, и удалите все ссылки на RedisController2, кроме при регистрации.

person Aron    schedule 29.12.2014