How to use method parameter attributes
Asked Answered
H

4

19

I've been struggling to find examples of how to write a custom attribute to validate method parameters, i.e., turn this form:

public void DoSomething(Client client)
{
    if (client.HasAction("do_something"))
    {
        // ...
    }
    else
    {
        throw new RequiredActionException(client, "do_something");
    }
}

into this:

public void DoSomething([RequiredAction(Action="some_action")] Client client)
{
    // ...
}

As far as I can tell, I need to add this attribute to my custom attribute, but I'm at a loss on how to access the decorated parameter Client:

[AttributeUsageAttribute(AttributeTargets.Parameter)]
public class RequireActionAttribute : System.Attribute
{
    public Type Action {get; set;}

    public RequireActionAttribute()
    {
        // .. How do you access the decorated parameter?
        Client client = ???

        if (!client.HasAction(Action))
        {
            throw new RequiredActionException(client, Action);
        }
    }
}
Harpist answered 17/6, 2013 at 14:44 Comment(2)
Why can't you simply accept an interface as the parameter? For example, you could have an IDoSomething.Sociolinguistics
You cannot access the decorated item from inside the attribute. Attributes sit against the type meta-data statically, so you actually get the attribute from the item. That said, the attribute could then have a method that takes an argument that is the item, but then you're using a sledgehammer to crack a walnut and could have done it a lot easier without attributes.Muncey
C
20

You're applying it correctly - but an attribute basically doesn't know the member it refers to. This definitely makes life harder.

Not only does it not have access to the member that it refers to, but that member would be a ParameterInfo, not a Client - there's no easy way of accessing the value of a parameter externally. Your method would need to call some helper code, passing the value of client in order to handle it appropriately... or you need to hook into the code which is going to call your method to start with, in order to notice the attribute.

It's not clear exactly how you were hoping to use this, but it may well be that you need to change your design significantly.

Competent answered 17/6, 2013 at 14:48 Comment(0)
F
5

Attributes are not enough for doing it.

If I understood you correctly you want to add an attribute on a parameter in order to validate it at run time and that is impossible only with attributes.

It is impossible because attributes are only "metadata" and not executed code.

You will need some "real" code to read it and act accordingly. That code can be injected at compile time or you can hook into the function execution.

Fruin answered 23/1, 2017 at 21:19 Comment(0)
J
1

Attributes probably should be put on the method itself. When I was searching for the solution I found the following link and the way it uses interceptor seems even better http://www.codinginstinct.com/2008/05/argument-validation-using-attributes.html

Jena answered 26/4, 2016 at 15:38 Comment(2)
Can you explain a bit more?Hydraulic
I might have misunderstood the original code. The link I posted uses interceptor to validate code. Comment doesn't allow me to post code from there. It just looks to me that this solution looks more elegant than the attribute validation we did in the past.Jena
R
0

After the decade it's still puzzling what for is this custom argument attribute... No way to manage it without overcomplicated interception.

Resect answered 11/2 at 14:49 Comment(1)
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From ReviewDigamma

© 2022 - 2024 — McMap. All rights reserved.