Hasan A Yousef Hasan A Yousef - 26 days ago 10
C# Question

Custom attributes declaration of multiple methods for the same attribute in C# dotnet core

As I mentioned in my other question here, and based on the answer given by @Abdul Rahman I was able to call/reject the call of the function under attribute using the below code:

using System;
using System.Linq; // for using Where
using System.Reflection;

namespace attribute
{
public class Program
{
public static int Main(string[] args)
{
var customAttributes = (MyCustomAttribute[])((typeof(Foo).GetTypeInfo())
.DeclaredMethods.Where(x => x.Name == "fn") // my question about this
.FirstOrDefault())
.GetCustomAttributes(typeof(MyCustomAttribute), true);
if (customAttributes.Length > 0)
{
var myAttribute = customAttributes[0];
string value = myAttribute.SomeProperty;
if (value == "bar")
Foo.fn();
else
Console.WriteLine("The attribute parameter is not as required");
}
return 0;
}
}
}


The Attribute and Foo classes are simple so far, as i'm in the learning stage:

[AttributeUsage(AttributeTargets.All)]
public class MyCustomAttribute : Attribute
{
public string SomeProperty { get; set; }
}


public class Foo
{
[MyCustom(SomeProperty = "bar")]
internal static void fn()
{
Console.WriteLine("a function in a class");
}

[MyCustom(SomeProperty = "bar")]
internal static void fn2()
{
Console.WriteLine("another function in the same class");
}
}

public class Foo2
{
[MyCustom(SomeProperty = "bar")]
internal static void fn2()
{
Console.WriteLine("another function in a nother class");
}
}


my question is about the
.DeclaredMethods.Where(x => x.Name == "fn")
do I need to repeat the same for every function I add, or there is a simple extension can do this for me, my target is simply like this, I need to check the attribute parameter, if it is matching with my input, I need the function under the attribute to start, if not matching, the function will not run. thanks

UPDATE
Added the sample code to the ideone.com for easy check
http://ideone.com/E9uL6r

Answer

I am assuming your methods are static. so they dont require an object instance.

 static  void ExecuteFunction(Type T,string functionName, string Value)
        {
            MethodInfo m = ((T.GetTypeInfo()).DeclaredMethods.Where(x => x.Name == functionName).FirstOrDefault());
            //var customAttributes = (MyCustomAttribute[])((T.GetTypeInfo()).DeclaredMethods.Where(x => x.Name == functionName).FirstOrDefault()).GetCustomAttributes(typeof(MyCustomAttribute), true);
            var customAttributes = (MyCustomAttribute[])(m.GetCustomAttributes(typeof(MyCustomAttribute), true));

            if (customAttributes.Length > 0)
            {
                var myAttribute = customAttributes[0];
                string value = myAttribute.SomeProperty;
                // TODO: Do something with the value
                Console.WriteLine(value);
                if (value == Value)
                {
                    m.Invoke(null, null);
                }
                else
                    Console.WriteLine("Unauthorized");
            }

        }

& Execute it as

 ExecuteFunction(typeof(Foo), "fn", "bar");

Edit : Updated Solution based on your Error: You are checking for string. you should get the class based on the string & then check for methods in it.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Reflection;

namespace ConsoleApp1Core
{
    [AttributeUsage(AttributeTargets.All)]
    public class MyCustomAttribute : Attribute
    {
        public string SomeProperty { get; set; }
    }


    public class Foo
    {
        [MyCustom(SomeProperty = "bar")]
        internal static void fn()
        {
            Console.WriteLine("a function in a class");
        }

        [MyCustom(SomeProperty = "bar")]
        internal static void fn2()
        {
            Console.WriteLine("another function in the same class");
        }
    }

    public class Foo2
    {
        [MyCustom(SomeProperty = "bar")]
        internal static void fn2()
        {
            Console.WriteLine("another function in a nother class");
        }
    }


    public class Program
    {
        public static int Main(string[] args)
        {
            var targetClasses = new HashSet<string>(new[] { "ConsoleApp1Core.Foo", "ConsoleApp1Core.Foo2" });
            var targetFns = new HashSet<string>(new[] { "fn", "fn2", "fn3" });
            var j = 0;
            foreach (var target in targetClasses)
            {
                Console.WriteLine("_class round {0}", j++);
                var i = 0;
                foreach (var fn in targetFns)
                {
                    Console.WriteLine("fn round {0}", i++);
                    Type t = Type.GetType(target);
                    var method = (t.GetTypeInfo()) // (typeof(Foo).GetTypeInfo())
                      .DeclaredMethods.Where(x => x.Name == fn).FirstOrDefault();
                    if (method != null) //return 0;
                    {
                        var customAttributes = (MyCustomAttribute[])method
                                               .GetCustomAttributes(typeof(MyCustomAttribute), true);
                        if (customAttributes.Length > 0)
                        {
                            var myAttribute = customAttributes[0];
                            string value = myAttribute.SomeProperty;
                            if (value == "bar")
                                method.Invoke(null, null);
                            //  Foo.fn();;
                            else
                                Console.WriteLine("The attribute parameter is not as required");
                        }
                    }
                    else
                    {
                        Console.WriteLine("Method not found");
                    }

                }
            }
            return 0;
        }
    }
}
Comments