簡體   English   中英

反射調用方法

[英]Invoke Method 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());

我無法調用我的“全名”方法。 這是我的界面:

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

您的問題在這一行:

Type theMathType = loadedAssem.GetType();

theMathType是Assembly,因此它不實現FullName。

你應該做:

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

順便說一句,如果您使用以下方法實例化theObj:

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

那么您可以簡單地編寫(無需使用反射來調用方法):

theObj.FullName("Mr. ");

您正在調用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 ,該程序集可被加載插件的代碼以及插件本身(可能是用於此類可擴展性類型的單獨程序集)訪問。

這樣,您可以將結果強制轉換為接口並正常使用。 必須以反射方式調用接口方法會破壞要求這種接口的目的。

我用這段代碼解決了這個問題。我們希望在單獨的類庫中使用接口“ 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