Question

Question: using only Assembly.LoadFrom and having only the name of a custom attribute how can I find and then instantiate any classes with that named custom attribute?

Code in DLL:

[AttributeUsage(AttributeTargets.All)]
public class ClassAttribute : Attribute
{
    private string myName;
    public ClassAttribute() { }
    public ClassAttribute(string className) 
    {
        myName = className;
    }
    public string MyName { get { return myName; } }
}

//Edit ... added this after initial post
[AttributeUsage(AttributeTargets.All)]
public class MethodAttribute : Attribute
{
    private string myMethodName;
    public MethodAttribute(){}
    public MethodAttribute(string methodName)
    {
        myMethodName = methodName;
    }
    public string MyMethodName { get { return myMethodName; } }
}

[ClassAttribute("The First Class")]
public class myClass
{
    //Edit ... added this after initial post
    [MethodAttribute("Find this method after finding this class")]
    public string methodOne()
    {
        return "This response from myclass methodOne";
    }

    public string methodTwo()
    {
        return "This response from myClass methodTwo";
    }
}

Code in consuming class in separate VS2k12 solution:

Assembly asm = Assembly.LoadFrom(@"C:\References\WebDemoAttributes.dll");

string attributeName = "Find this class using this attribute name";

//using attributeName how can I find WebDemoAttributes.myClass, instantiate it, and then call methodOne()?

Thank you in advance and cheers!


This is what I finally came up with for anyone interested in searching for classes in a DLL by custom attribute:

protected void lb_debugInClassLibrary_Click(object sender, EventArgs e)
{
    LinkButton lb = sender as LinkButton;

    Assembly asm1 = Assembly.Load("WebDemoAttributes");

    var classAttributesTypes = asm1.GetTypes().Where(t => t.GetCustomAttributes()
        .Any(a => a.GetType().Name == "ClassAttribute")).ToList();

    foreach (Type type in classAttributesTypes)
    {               
        Attribute[] attrs = Attribute.GetCustomAttributes(type);               

        foreach (Attribute atr in attrs)
        {
            var classWithCustomAttribute = atr as WebDemoAttributes.ClassAttribute;
            if (classWithCustomAttribute.MyName == "The First Class" 
                && lb.ID.ToString().ToLower().Contains("thefirstclass"))
            {
                var mc = Activator.CreateInstance(type) as WebDemoAttributes.MyClass;
                //TODO figure out how to get the attributes decorating mc's methods
                if (lb.ID.ToString().ToLower().Contains("methodone"))
                    lbl_responseFromMyClass.Text = mc.MethodOne();
                else if (lb.ID.ToString().ToLower().Contains("methodtwo"))
                    lbl_responseFromMyClass.Text = mc.MethodTwo();
            } 
            if (classWithCustomAttribute.MyName == "The Second Class" 
                && lb.ID.ToString().ToLower().Contains("thesecondclass"))
            {
                var yc = Activator.CreateInstance(type) as WebDemoAttributes.YourClass;
                if (lb.ID.ToString().ToLower().Contains("methodone"))
                    lbl_responseFromYourClass.Text = yc.MethodOne();
                else if (lb.ID.ToString().ToLower().Contains("methodtwo"))
                    lbl_responseFromYourClass.Text = yc.MethodTwo();
            }
        }
    }
}
Was it helpful?

Solution

var asm = Assembly.LoadFrom(@"C:\References\WebDemoAttributes.dll");

var myClassType = asm.GetTypes()
                     .FirstOrDefault(t => t.GetCustomAttributes()
                     .Any(a => a.GetType().Name == "ClassAttribute"));

OTHER TIPS

Your question:

using attributeName how can I find WebDemoAttributes.myClass, instantiate it, and then call methodOne()?

The answer: Don't use attributes. Use interfaces instead.

Attributes are used to set compile-time properties associated with classes that are accessible via reflection. They can be used to mark classes, methods, and assemblies, such that you can search for those specific items based on the existence of the attribute.

They cannot be used to enforce design constraints (at least, not out of the box). So, asking if you can locate a given class via attribute search, and then invoke methodOne() on the class, is not a valid question, because the existence of the attribute on the class does not imply the existence of methodOne.

Instead, I would suggest the use of an interface. You can find all classes that implement an interface, and invoke the method using reflection. This post gives a simple overview of that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top