如何从一个静态方法调用一个实例类方法与反射 [英] How to call an instance class method from a static method with reflection

查看:198
本文介绍了如何从一个静态方法调用一个实例类方法与反射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这被静态调用,并给出我一个答案

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

但是,当我尝试使用下面的dll调用它失败,因为它不是静态的

  Assembly testAssembly = Assembly.LoadFile(strDLL); 
键入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);

我只需要知道我必须对dll类做什么修改才能调用这里

解决方案

您必须将类型的实例传递给 InvokeMember

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






如果您正在创建一个插件,一个包含插件的接口声明的类库(dll)
$ b $ >

  • 包含接口(插件)实现的类库(dll)

  • 可执行文件(exe)加载插件

  • 接口DLL由其他两个组件引用。您需要三个程序集,因为插件不应该知道您的应用程序,应用程序不应该知道除了其界面之外的插件。这使得插件可互换和不同的应用程序可以使用相同的插件。






    接口装配 Calculator.Contracts.dll

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






    插件实现 Calculator.dll

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






    现在,您可以加载插件并在应用程序(exe)中以类型方式使用它:

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

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


    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

    解决方案

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

    这篇关于如何从一个静态方法调用一个实例类方法与反射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆