0

我创建了一个类库项目并构建它。现在我将 Dll 复制到“C:\”。现在我想用反射打开这个 Dll:

using System.Reflection;

        byte[] assem = System.IO.File.ReadAllBytes(@"c:\Company.dll");
        var loadedAssem = Assembly.Load(assem);
        Type thePersonType = loadedAssem.GetType();
        var theObj = loadedAssem.CreateInstance("Company.Person");
        // or  var theObj = loadedAssem.CreateInstance("Company.Person")as IPlugin ;
        Type[] paramTypes = new Type[1];
        paramTypes[0] = Type.GetType("System.String");
        MethodInfo PersonInfo = thePersonType.GetMethod("FullName", paramTypes);
        Object[] parameters = new Object[1];
        parameters[0] = "Mr. ";
        Object returnVal = PersonInfo.Invoke(theObj, parameters);
        MessageBox.Show(returnVal.ToString());

我不能调用我的“FullName”方法。这是我的界面:

public interface IPlugin
{
    String FullName(String PreName);
}

这是我的 DLL 中的 Person 类:

public class Person:IPlugin
{
    public int PersonID { get; set; }
    public String PersonName { get; set; }
    public String PersonLName { get; set; }
    public String FullName(String PreName)
    {
        return PreName+this.PersonName + this.PersonLName;
    }
}
4

3 回答 3

2

您的问题出在这一行:

Type theMathType = loadedAssem.GetType();

theMathType 是Assembly,所以它没有实现FullName。

你应该做:

Type theMathType = loadedAssem.GetType("Company.Person");

顺便说一句,如果您使用以下命令实例化 theObj:

IPlugin theObj = Activator.CreateInstance(theMathType) as IPlugin;

那么您可以简单地编写(不使用反射来调用该方法):

theObj.FullName("Mr. ");
于 2012-06-06T07:25:18.763 回答
2

您正在调用GetType(),它Assembly作为类型返回。这显然不是您要寻找的类型。要枚举程序集中声明的类型,请使用该Assembly.GetTypes()方法。
要查找实现的所有类型IPlugin,您可以使用以下代码:

Type[] iPluginTypes = (from t in loadedAssem
                       where !t.IsInterface && !t.IsAbstract
                       where typeof(IPlugin).IsAssignableFrom(t)
                       select t).ToArray();

另外(如果尚未完成)我建议您在程序集中声明接口IPlugin,该程序集可由加载插件的代码以及插件本身访问(可能是一个单独的程序集,仅用于类似的可扩展性类型)。

这样您就可以将结果转换为界面并正常使用它。不得不用反射类型调用接口方法违背了需要这样一个接口的目的。

于 2012-06-06T07:29:10.573 回答
1

我用这段代码解决了这个问题。我们应该在单独的类库中使用接口“IPlugin”并在其他项目中使用。

        Assembly objAssembly = Assembly.LoadFrom("Company.dll");
        Type objAssemblyType = objAssembly.GetType();

        foreach (Type type in objAssembly.GetTypes())
        {
            if (type.IsClass == true)
            {
                var classInstance = objAssembly.CreateInstance(type.ToString()) as IPlugin;
                lblFullName.Text = classInstance.FullName("Mr. ");

            }
        }
于 2012-06-06T11:57:19.713 回答