ninjectninject-extensionsninject-interception

Ninject retrieve Custom Attributes on parameters inside interceptor


I am attempting to enumerate the parameters of a decorated method to retrieve the custom attributes applied to those parameters to determine a specific value.

I have the following in my interceptor, which shows two different methods that I tried to use, both retreiving and enumerating GetParameters but one using IsDefined and the other using GetCustomAttributes:

public void Intercept(IInvocation invocation)
{
    try
    {

        var parameters = invocation.Request.Method.GetParameters();
        for (int index = 0; index < parameters.Length; index++)
        {
            foreach (var attrs in parameters[index]
                .GetCustomAttributes(typeof(EmulatedUserAttribute), true))
            {

            }

        }

        foreach (var param in invocation.Request.Method.GetParameters())
        {
            if (param.IsDefined(typeof (EmulatedUserAttribute), false))
            {
                invocation.Request.Arguments[param.Position] = 12345;
            }

        }


        invocation.Proceed();
    }
    catch(Exception ex)
    {
        throw;
    }
}

The attribute I am looking for is simple, no implementation:

public class EmulatedUserAttribute : Attribute { }

And the InterceptAttribute:

[AttributeUsage(AttributeTargets.Method)]
public class EmulateAttribute : InterceptAttribute
{
    public override IInterceptor CreateInterceptor(IProxyRequest request)
    {
        return request.Context.Kernel.Get<IEmulateUserInterceptor>();
    }
}

And the method I am intercepting:

[Emulate]
public virtual List<UserAssociation> GetAssociatedProviders([EmulatedUser] int userId)
{
    return _assocProvAccountRepo.GetAssociatedProviders(userId);
}

As you can see I decorated the userId with the EmulatedUser attribute, and the method with my interceptor attribute. Everything else works fine except that I cannot see the attribute on userId.

Any ideas why I cant see custom attributes on the method? Im guessing it has something to do with the Method not being the actual "invocation target" but I dont see any way to get around this. Please help!


Solution

  • Brandon,

    Try this code out. I have made it work just fine. Here is how I defined the classes:

    public class Interceptor : SimpleInterceptor
    {
        protected override void BeforeInvoke(IInvocation invocation)
        {
            var invokedMethod = invocation.Request.Method;
            if (invokedMethod.IsDefined(typeof(EmulateAttribute), true))
            {
                var methodParameters = invokedMethod.GetParameters();
                for (int i = 0; i < methodParameters.Length; i++)
                {
                    var param = methodParameters[i];
                    if (param.IsDefined(typeof (EmulatedUserAttribute), true))
                    {
                        invocation.Request.Arguments[i] = 5678;
                    }
                }
            }
        }
    }
    
    public interface IIntercepted
    {
        [Emulate]
        void InterceptedMethod([EmulatedUser] int userId);
    }
    
    public class Intercepted : IIntercepted
    {
        [Emulate]
        public void InterceptedMethod([EmulatedUser] int userId)
        {
            Console.WriteLine("UserID: {0}", userId);
        }
    }
    

    I am requesting an instance of IIntercepted instead of Intercepted. If I request the concrete class, the interception will not work. Maybe this can get you in the right path.

    var kernel = new StandardKernel();
    kernel.Bind<IIntercepted>().To<Intercepted>().Intercept().With<Interceptor>();
    
    var target = kernel.Get<IIntercepted>();
    
    target.InterceptedMethod(1234); // Outputs 5678