无法使用DynamicProxy在Interceptor中检索CustomAttributes

时间:2011-06-04 16:41:13

标签: .net castle castle-dynamicproxy

我目前正在使用Castle DynamicProxy实现拦截器。我要求拦截器在我的服务层方法上获取一些自定义属性,但是invocation.Method.GetCustomAttributes什么都不返回。我可能做错了什么?

截获方法:

 [Transaction()]
 [SecurityRole(AuthenticationRequired = false, Role = SystemRole.Unauthorised)]
 public virtual void LoginUser(out SystemUser userToLogin, string username)
 {
     ...
 }

拦截器:

// Checks that a security attribute has been defined
foreach (SecurityRoleAttribute role in invocation.Method.GetCustomAttributes(typeof(SecurityRoleAttribute), true))
{
    if (!securityAttributeDefined)
        securityAttributeDefined = true;
}

我也试过了:

Attribute.GetCustomAttribute(invocation.Method, typeof(SecurityRoleAttribute), true);

更新:

可能是配置问题。配置代码如下:

InterceptorsInstaller:

    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
         container.Register(
            Component.For<LoggingInterceptor>()
            .Named("LoggingInterceptor"));

         container.Register(
            Component.For<SecurityInterceptor>()
            .Named("SecurityInterceptor"));

         container.Register(
            Component.For<ValidationInterceptor>()
            .Named("ValidationInterceptor"));
    }

的ServiceInstaller:

    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        string[] interceptors = {"LoggingInterceptor", "SecurityInterceptor"};

        container.Register(AllTypes.FromAssemblyContaining<BaseService>().Pick()
                            .If(Component.IsInSameNamespaceAs<LoginService>())
                            .Configure(c => c
                                               .LifeStyle.Transient
                                               .Interceptors(interceptors))
                            .WithService.DefaultInterface());
    }

我正在使用Castle 2.5.2 / .Net 3.5。

谢谢,

2 个答案:

答案 0 :(得分:5)

原来这是因为代理是一个接口代理。获取方法调用目标,然后从methodInfo获取属性修复它:

    MethodInfo methodInfo = invocation.MethodInvocationTarget; 
    if (methodInfo == null) { 
        methodInfo = invocation.Method; 
    }

答案 1 :(得分:1)

您的拦截器代码没问题,但您注册错了。你写的是“如果我问你IInterceptor,请给我SecurityInterceptor”。你想说“使用LoginUser()”拦截对包含Foo(让我们称之为SecurityInterceptor)的类的调用。翻译成C#,看起来像这样:

container.Register(Component.For<Foo>().Interceptors<SecurityInterceptor>());
container.Register(Component.For<SecurityInterceptor>().Named("SecurityInterceptor"));