-2

问题:仅使用 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();
            }
        }
    }
}
4

2 回答 2

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

var myClassType = asm.GetTypes()
                     .FirstOrDefault(t => t.GetCustomAttributes()
                     .Any(a => a.GetType().Name == "ClassAttribute"));
于 2014-01-25T15:07:48.087 回答
0

你的问题:

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

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

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

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

相反,我建议使用interface。您可以找到所有实现接口的类,并使用反射调用该方法。 这篇文章给出了一个简单的概述。

于 2014-01-25T15:05:24.323 回答