lundi 8 mai 2017

Mapping a single-method-to-multiple-strings Dictionary to a single-string-to-multiple-method Dictionary

I Dare say that's the most complicated title I've ever come up with. I'm just not sure how to better explain it, short of this example:

I have a type. Under this type, I have assorted methods, some of which have one or more "OnAttribute" attributes attached to them, each defining an event name this method needs to fire on. I'm currently getting a Dictionary of Methods to their relevant lists of event names with this query:

var methods = this.GetType().GetMethods()
    .Where(m => Attribute.IsDefined(m, typeof(OnAttribute)))
    .ToDictionary(m => m,
        m => m.GetCustomAttributes(typeof(OnAttribute), true)
            .Select(a => ((OnAttribute)a).EventName)); //OnAttribute defines an EventName field

The resulting type is IEnumerable<IGrouping<System.Reflection.MethodInfo,IEnumerable<string>>>. However, in order to sign the methods up for their requested events, I need to map each event name to any and all methods asking to execute on them. In other words, I need the previously mentioned type mapped to IEnumerable<IGrouping<string,IEnumerable<System.Reflection.MethodInfo>>>.

I need this:

[On("Event_1")]
[On("Event_2")]
[On("Event_4")]
void Method_1()
{
    ...
}

[On("Event_1")]
void Method_2()
{
     ...
}

[On("Event_2")]
[On("Event_3")]
void Method_3()
{
    ...
}

Which, using my current code, would map to this:

Method_1 => ["Event_1","Event_2","Event_4"]
Method_2 => ["Event_1"]
Method_3 => ["Event_2","Event_3"]

Instead mapped to this:

"Event_1" => [Method_1,Method_2]
"Event_2" => [Method_1,Method_3]
"Event_3" => [Method_2]
"Event_4" => [Method_1]

I'm sure there's some better terminology out there somewhere to describe this; I just don't know what it is.

I attempted using a foreach loop to create a dictionary the ugly way, but as I said, that's really ugly. I also attempted to use SelectMany() with some anonymous types to flatten the Dictionary into a list, and then use GroupBy to re-group that list into my desired dictionary, but that seemed inefficient and messy. I'd like to know the (best) LINQ way of doing this.

I hope that made at least a little bit of sense.

Thanks for any help!





Aucun commentaire:

Enregistrer un commentaire