2014-01-15 7 views
4

У меня есть перехватчик замка, который я пытаюсь применить через атрибуты. Он отлично работает, когда я применяю атрибут Interceptor на уровне класса, но он не работает вообще, когда я применяю метод на уровне метода. Что я делаю не так? Я не хочу перехватывать каждый метод в классе, но вместо этого отмечать определенные методы с помощью атрибута [Перехватчик]. Я пробовал маркировать свои методы как виртуальные, но это все еще не работает. Вот мой код:Замок Виндзорский перехватчик не работает с атрибутом уровня метода

Это работает и все методы перехватываются:

[Interceptor(typeof(CacheInterceptor))] 
public class Foo : IFoo 
{ 
    public int SomeMethod() { } 
} 

Это не работает (атрибут на уровне метода):

public class Foo : IFoo 
{ 
    [Interceptor(typeof(CacheInterceptor))] 
    public int SomeMethod() { } 
} 

Установщик:

public class CacheInterceptorInstaller : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     container.Register(Component.For<CacheInterceptor>().LifeStyle.Singleton); 

     container.Register(Component 
      .For<ICacheProvider>() 
      .LifeStyle.Singleton 
      .ImplementedBy<CacheProvider>()); 
    } 
} 

Перехватчик:

public class CacheInterceptor : IInterceptor 
{ 
    private readonly ICacheProvider _cacheProvider; 

    public CacheInterceptor(ICacheProvider cacheProvider) 
    { 
     _cacheProvider = cacheProvider; 
    } 

    public void Intercept(IInvocation invocation) 
    { 
     // do interception stuff 
    } 
} 

Спасибо,

Энди

ответ

3

К сожалению, я не думаю, что есть способ, чтобы использовать атрибут Interceptor только на методе. От http://docs.castleproject.org/Windsor.Interceptors.ashx:

InterceptorAttribute определяется таким образом, что позволяет положить его не только на классы, но и на любой другой цели, где пользовательский атрибут разрешен, подобный интерфейс или метод. Однако Windsor игнорирует атрибут, если он не находится на классе реализации компонента. Это разрешительное поведение было введено, чтобы люди могли добавлять поддержку других целей путем создания пользовательских расширений.

(выделено мной)

Я думаю, что то, что может быть полезным в замке является IProxyGenerationHook и/или IInterceptorSelector. Некоторая документация по этому вопросу: http://docs.castleproject.org/Tools.Use-proxy-generation-hooks-and-interceptor-selectors-for-fine-grained-control.ashx

Но, я не вижу никакого способа использования IInterceptorSelector с атрибутом Interceptor.

+0

Это делает меня грустным. Я довольно новичок в AOP, но похоже, что перехватчики на уровне методов будут хорошей возможностью предложить. Спасибо за помощь! – Andy

+0

Просто обратите внимание, что с PostSharp гораздо проще делать то, что вы пытаетесь :) –

7

Вы можете использовать пользовательский атрибут для выбора методов перехвата:

[Interceptor(typeof(CacheInterceptor))] 
public class Foo : IFoo 
{ 
    [Cache] 
    public int SomeMethod() { } 
} 

Затем в Intercept метод проверки, если метод имеет пользовательский атрибут:

if (invocation.MethodInvocationTarget.IsDefined(typeof(CacheAttribute))) { 
    // do interception stuff 
} 
+0

Спасибо - это хорошее обходное решение. Надеюсь, есть более чистый способ сделать это, не перехватывая все методы класса. – Andy