C
C#7mo ago
Kiel

Using reflection to build a dictionary of methods -> attributes at runtime

I'd like the following setup to work:
[Request(GET, "/something/{0}")]
public static async Task<...> GetSomethingAsync(int foo, ...)
{
var request = CreateRequest(foo);
}

private static HttpRequestMessage CreateRequest(params object[] data)
{
// I'd like to be able to access the values of the [Request] attribute in GetSomethingAsync()
// via a lookup table (dictionary) generated once at runtime, so that I don't have to use StackTrace/StackFrame
// every single time, which hurts performance greatly.
var method = GetCallingMethodInfoFromLookup();
var requestAttribute = method.GetCustomAttribute<RequestAttribute>();
return new HttpRequestMessage(requestAttribute.Method, string.Format(requestAttribute.Route, data));
}
[Request(GET, "/something/{0}")]
public static async Task<...> GetSomethingAsync(int foo, ...)
{
var request = CreateRequest(foo);
}

private static HttpRequestMessage CreateRequest(params object[] data)
{
// I'd like to be able to access the values of the [Request] attribute in GetSomethingAsync()
// via a lookup table (dictionary) generated once at runtime, so that I don't have to use StackTrace/StackFrame
// every single time, which hurts performance greatly.
var method = GetCallingMethodInfoFromLookup();
var requestAttribute = method.GetCustomAttribute<RequestAttribute>();
return new HttpRequestMessage(requestAttribute.Method, string.Format(requestAttribute.Route, data));
}
Is this possible? While trying to find out how to do this at all I found that I could use something similar to new StackFrame(1).GetMethod() to retrieve the calling method, adjusting the 1 to the level of nesting in the method, but this is 1) extra hacky IMO and 2) seems like it has serious negative performance impacts. Something I have considered is using [CallerMemberName] to make it a lookup based solely on method names, but as I've just started defining all these methods I have no clue if I will be making methods with overloads, IE ending up with two or more methods with the same name, making the lookup not possible.
2 Replies
exokem
exokem7mo ago
For clarity: Do you want to collect all methods with the request attribute and pass them the appropriate parameters based on the URL format?
Kiel
Kiel7mo ago
the goal is to be able to access the values in the [Request] attribute from within the method itself so I can make them a little more visible to me at compile time instead of defining them in the method themselves