Атрибутированный перехват на уровне метода с помощью Autofac

(это вопрос, связанный с этим для SimpleInjector. Я был рекомендуется создавать отдельные вопросы для каждого контейнера IoC.)

С Unity я могу быстро добавить перехват на основе атрибутов, подобный этому

public sealed class MyCacheAttribute : HandlerAttribute, ICallHandler
{
   public override ICallHandler CreateHandler(IUnityContainer container)
   {
        return this;
   }

   public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
   {
      // grab from cache if I have it, otherwise call the intended method call..
   }
}

Затем я регистрируюсь в Unity следующим образом:

  container.RegisterType<IPlanRepository, PlanRepository>(new ContainerControlledLifetimeManager(),
           new Interceptor<VirtualMethodInterceptor>(),
           new InterceptionBehavior<PolicyInjectionBehavior>());

В моем коде репозитория я могу выборочно украшать определенные методы для кэширования (со значениями атрибутов, которые можно настроить индивидуально для каждого метода):

    [MyCache( Minutes = 5, CacheType = CacheType.Memory, Order = 100)]
    public virtual PlanInfo GetPlan(int id)
    {
        // call data store to get this plan;
    }

Я изучаю аналогичные способы сделать это в Autofac. Из того, что я читал и искал, похоже, что доступен только перехват на уровне интерфейса/типа. Но мне бы очень хотелось украсить отдельные методы таким типом поведения перехвата, контролируемого атрибутами. Любой совет?


person Calvin    schedule 10.03.2015    source источник


Ответы (1)


Вы правы, когда говорите, что нет перехвата на уровне метода. Однако, когда вы используете запись перехватчика типа, у вас есть доступ к вызываемому методу. Примечание: это зависит от пакета Autofac.Extras.DynamicProxy2.

    public sealed class MyCacheAttribute : IInterceptor
    {

        public void Intercept(IInvocation invocation)
        {
            // grab from cache if I have it, otherwise call the intended method call..

            Console.WriteLine("Calling " + invocation.Method.Name);

            invocation.Proceed();
        }
    }

Регистрация будет примерно такой.

     containerBuilder.RegisterType<PlanRepository>().As<IPlanRepository>().EnableInterfaceInterceptors();
     containerbuilder.RegisterType<MyCacheAttribute>();
person gaunacode.com    schedule 10.03.2015
comment
Похоже, что и Autofac, и SimpleInjector используют динамический прокси-сервер, и встроенной поддержки перехвата с атрибутами нет. Стивен предоставил типичное решение для перехвата интерфейса здесь: stackoverflow.com/a/28969513/879655 - person Calvin; 11.03.2015
comment
@Calvin: Чтобы быть более точным: Simple Injector даже не поддерживает перехват. Пакета или расширения для перехвата нет. - person Steven; 12.03.2015