简体   繁体   English

反射调用方法

[英]Invoke Method with reflection

I create a Class Library project and I build it.now i copy the Dll to "C:\\".Now i want to open this Dll with reflection: 我创建一个类库项目并构建它。现在将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());

I cant Invoke my "FullName" method. 我无法调用我的“全名”方法。 this is my Interface: 这是我的界面:

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

and this is my Person Class in my DLL: 这是我的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;
    }
}

Your problem is in this line: 您的问题在这一行:

Type theMathType = loadedAssem.GetType();

theMathType is Assembly, so it does not implement FullName. theMathType是Assembly,因此它不实现FullName。

You should do: 你应该做:

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

BTW, if you instantiate theObj with: 顺便说一句,如果您使用以下方法实例化theObj:

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

then you can simply write (without using reflection to invoke the method): 那么您可以简单地编写(无需使用反射来调用方法):

theObj.FullName("Mr. ");

You are calling GetType() , which returns Assembly as type. 您正在调用GetType() ,该方法返回Assembly作为类型。 That is obviously not the type you are looking for. 那显然不是您要查找的类型。 To enumerate over the types declared in an assembly, use the Assembly.GetTypes() method. 要枚举程序集中声明的类型,请使用Assembly.GetTypes()方法。
To find all types that implement IPlugin , you could use this code: 要查找实现IPlugin所有类型,可以使用以下代码:

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

Also (if not already done) i would suggest that you declare the interface IPlugin in an assembly that is accessible by both the code that is loading the plugins as well as the plugins themselves (maybe a separate assembly just for extensibility types like that). 另外(如果尚未完成的话)我建议您在一个程序集中声明接口IPlugin ,该程序集可被加载插件的代码以及插件本身(可能是用于此类可扩展性类型的单独程序集)访问。

That way you could just cast the result to the interface and use it normally. 这样,您可以将结果强制转换为接口并正常使用。 Having to invoke the interface methods with reflection kind of defeats the purpose of requiring such an interface. 必须以反射方式调用接口方法会破坏要求这种接口的目的。

I solve the problem with this code.and we shold to use interface "IPlugin" in a seperate class library and use in other project. 我用这段代码解决了这个问题。我们希望在单独的类库中使用接口“ 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. ");

            }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM