mardi 25 avril 2017

How to use C# attributes to select a method in a class based on a string?

Suppose I have a class like this:

public class MyMethods
{

    [SpecialMethod("test")]
    public string GetTestString(int i)
    {
        return string.Format("Hello world {0} times!",i);
    }

    [SpecialMethod("lorem")]
    public string GetSomeLoremIpsumText(int i)
    {
        // ignores the 'i' variable
        return "Lorem ipsum dolor sit amet";
    }

    // ... more methods with the same signature here ...

    public string DefaultMethod(int i)
    {
        return "The default method happened! The attribute wasn't found.";
    }

    public string ThisMethodShouldNotShowUpViaAttributes(int i)
    {
        return "You should not be here.";
    }
}

I also have defined the attribute simply like this:

[AttributeUsage(AttributeTargets.Method)]
public class SpecialMethodAttribute : System.Attribute 
{
    private string _accessor;
    public string Accessor 
    {
        get 
        {
            return _accessor;
        }
    }
    public SpecialMethodAttribute(string accessor)
    {
        _accessor = accessor;
    }
}

What I want to be able to do might look like this:

public class MethodAccessViaAttribute
{
    private MyMethods _m;

    public MethodAccessViaAttribute()
    {
        _m = new MyMethods();
    }

    public string CallMethodByAccessor(string accessor, int i)
    {
        // this is pseudo-code, expressing what I want to be able to do.
        Func<int, string> methodToCall = FindAMethodByAttribute(_m, accessor);
        if (methodToCall == null)
            return _m.DefaultMethod(i);
        else
            return methodToCall(i);
    }

    public void Test()
    {
        // should print "Hello world 3 times!"
        Console.WriteLine(CallMethodByAccessor("test",3));

        // should print "Lorem ipsum dolor sit amet"
        Console.WriteLine(CallMethodByAccessor("lorem",int.MaxValue));

        // should print "The default method happened! The attribute wasn't found."
        Console.WriteLine(CallMethodByAccessor("I-do-not-exist",0));
    }
}

Notice that all methods using the SpecialMethod attribute follow the same method signature. Ideally, the search function would exclude methods not matching the signature, since a try/catch could be used if the method doesn't match the Func signature.

Can I get a point in the right direction for how to accomplish this?





Aucun commentaire:

Enregistrer un commentaire