Assembly.LoadFrom获取自定义属性

时间:2014-01-25 14:55:13

标签: c# .net .net-assembly getcustomattributes

问题:仅使用Assembly.LoadFrom并且只使用自定义属性的名称如何找到并使用该命名自定义属性实例化任何类?

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";
    }
}

单独的VS2k12解决方案中的消费类代码:

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

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

//使用attributeName如何找到WebDemoAttributes.myClass,实例化它,然后调用 methodOne()?

提前谢谢你并欢呼!


对于有兴趣通过自定义属性在DLL中搜索类的人,我最终想出了这个:

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();
            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

你的问题:

  

使用attributeName如何找到WebDemoAttributes.myClass,实例化它,然后调用methodOne()?

答案: 不要使用属性。改为使用接口。

Attributes 用于设置与可通过反射访问的类关联的编译时属性。它们可用于标记类,方法和程序集,以便您可以根据属性的存在来搜索这些特定项。

它们不能用于强制执行设计约束(至少不是开箱即用)。因此,询问是否可以通过属性搜索找到给定的类,然后在类上调用methodOne(),这不是一个有效的问题,因为类上的属性的存在并不意味着存在{{1 }}

相反,我建议使用接口。您可以找到实现接口的所有类,并使用反射调用该方法。 This post简要概述了这一点。

答案 1 :(得分:0)

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

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