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!
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