【问题标题】:Cannot retrieve CustomAttributes in Interceptor using DynamicProxy无法使用 DynamicProxy 在拦截器中检索 CustomAttributes
【发布时间】:2011-06-08 21:18:10
【问题描述】:

我目前正在使用 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。

谢谢,

保罗

【问题讨论】:

  • 你确定这个方法被拦截了?它没有被声明为虚拟的,所以如果你使用CreateClassProxy(),它不会被拦截。
  • 啊,添加进去了。我可以调试拦截器,所以可以跟踪拦截的其余部分,但不要取回任何属性。像这样注册容器: container.Register( Component.For() .ImplementedBy() .Named("SecurityInterceptor"));

标签: .net castle castle-dynamicproxy


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您的拦截器代码很好,但您注册错误。你写的意思是“如果我问你IInterceptor,给我SecurityInterceptor”。您想说“使用SecurityInterceptor 拦截对包含LoginUser() 的类的调用(我们称之为Foo)”。翻译成C#,是这样的:

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

    【讨论】:

    • 感谢 svick,更新了配置,但没有骰子。我现在已经在我原来的帖子中包含了配置部分,因为它可能仍然是一个配置问题。
    猜你喜欢
    • 1970-01-01
    • 2012-03-31
    • 2012-12-26
    • 2023-03-03
    • 2011-06-22
    • 1970-01-01
    • 2018-10-06
    • 2012-12-07
    • 2018-06-23
    相关资源
    最近更新 更多