简体   繁体   中英

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:

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:

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.

You should do:

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

BTW, if you instantiate theObj with:

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. That is obviously not the type you are looking for. To enumerate over the types declared in an assembly, use the Assembly.GetTypes() method.
To find all types that implement IPlugin , you could use this code:

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).

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.

        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. ");

            }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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