How to call an instance class method from a static method with reflection

亡梦爱人 提交于 2019-12-12 00:49:21

问题


namespace ClassLibraryB {
    public class Class1 {
        public void Add(int ii, int jj)
        {
            i = ii;
            j = jj;
            result = i + j;
        }
        public void Add2()
        {
            result =  i + j;
        }
    }
}

This gets called statically and gives me an answer

ClassLibraryB.Class1 objB = new ClassLibraryB.Class1();
objB.Add(4, 16);
objB.Add2();
kk = objB.result;
textBox1.Text += "Addition =" + kk.ToString() + "\r\n";

However when I try to call the dll using below it fails with since it is not static

Assembly testAssembly = Assembly.LoadFile(strDLL);
Type calcType = testAssembly.GetType("ClassLibraryB.Class1");
object calcInstance = Activator.CreateInstance(calcType);
PropertyInfo numberPropertyInfo = calcType.GetProperty("i");
numberPropertyInfo.SetValue(calcInstance, 5, null);
PropertyInfo numberPropertyInfo2 = calcType.GetProperty("j");
numberPropertyInfo2.SetValue(calcInstance, 15, null);
int value2 = (int)numberPropertyInfo.GetValue(calcInstance, null);
int value3 = (int)numberPropertyInfo2.GetValue(calcInstance, null);
calcType.InvokeMember("Add2",BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
    null, null, null);
PropertyInfo numberPropertyInfo3 = calcType.GetProperty("result");
int value4 = (int)numberPropertyInfo3.GetValue(calcInstance, null);

I just need to know exactly what changes I have to make to the dll class to be able to call it here


回答1:


You must pass an instance of the type to InvokeMember

calcType.InvokeMember("Add2", flags, null, calcInstance, null);

If you are creating a plug-in, the right thing to do is to have three assemblies.

  1. A class library (dll) containing an interface declaration of the plug-in
  2. A class library (dll) containing an implementation of the interface (the plug-in)
  3. An executable (exe) loading the plug-in

The interface DLL is referenced by the two other components. You need three assemblies because the plug-in should not know anything about your application and the application should not know anything about your plug-in other than its interface. This makes the plug-ins interchangeable and different applications can use the same plug-in.


Interface Assembly Calculator.Contracts.dll

public interface ICalculator
{
    int Add(int a, int b);
}

Plug-in implementation Calculator.dll

public class Calculator : ICalculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}

Now you can load the plug-in and use it in a typed way in the application (exe):

Assembly asm = Assembly.LoadFrom(strDLL);
string calcInterfaceName = typeof(ICalculator).FullName;
foreach (Type type in asm.GetExportedTypes()) {
    Type interfaceType = type.GetInterface(calcInterfaceName);
    if (interfaceType != null &&
        (type.Attributes & TypeAttributes.Abstract) != TypeAttributes.Abstract) {

        ICalculator calculator = (ICalculator)Activator.CreateInstance(type);
        int result = calculator.Add(2, 7);
    }
}


来源:https://stackoverflow.com/questions/22546533/how-to-call-an-instance-class-method-from-a-static-method-with-reflection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!