UH4L3——实例化ILRuntime中对象

本章代码关键字

1
2
3
4
5
appDomain.Instantiate()        //通过appDomain去实例化热更工程内的一个对象
IType //ILRuntime封装的类型相关的接口
appDomain.LoadedTypes[] //通过"命名空间.类名"获取一个IType对象,提供它可以获取对象
ILType.Instantiate() //将IType强转为ILType后可以获取该方法实例化对象
IType.ReflectionType //获取热更新工程内的Type消息,之后可以基于这个Type反射构造函数再实例化方法

在ILRuntime热更工程中新建一个类

Unity中实例化ILRuntime中类对象主要有三种方式

  1. appDomain​中的Instantiate​方法
  2. appDomain​中LoadedTypes​字典获取IType​类型后, 强转为ILType​后调用Instantiate​方法
  3. appDomain​中LoadedTypes​字典获取IType​类型后, 再去获取它的构造函数信息用于实例化对象

推荐使用方式2或者3,因为他们都需要先获取IType,之后调用对象中成员时更方便

先在ILRuntime的工程中新建一个类,并为该类声明几个构造函数重载,然后重新生成dll和pdb文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace HotFix_Project
{
public class Lesson3_Test
{
public string str;

public Lesson3_Test() { }

public Lesson3_Test(string str)
{
this.str = str;
}
}
}

在Unity中跨域调用ILRuntime中的类

更推荐方式二,因为之后在调用对象方法变量时,通过方式二更方便

  • 方式一:appdomain​中的Instantiate​方法

    注意,我们无法在Unity主工程内直接使用ILRuntime热更新工程内的类型变量,我们只能使用object​来装载实例化出来的内容

    • 参数一:类的命名空间.类名
    • 参数二:参数列表,如果不传入,则默认调用无参构造函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void Start()
    {
    ILRuntimeMgr.Instance.StartILRuntime(() =>
    {
    AppDomain appDomain = ILRuntimeMgr.Instance.appDomain;
    object obj = appDomain.Instantiate("HotFix_Project.Lesson3_Test");
    print(obj);
    obj = appDomain.Instantiate("HotFix_Project.Lesson3_Test", new object[] { "123" });
    print(obj);
    });
    }

    输出:image

  • 方式二:appdomain​中LoadedTypes​字典获取IType​类型后,强转为ILType​后调用Instantiate​方法,该方式类似反射

    如果要调用有参构造,则ILType​需要传入object[]​,内部就是有参构造需要的参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void Start()
    {
    ILRuntimeMgr.Instance.StartILRuntime(() =>
    {
    IType type = appDomain.LoadedTypes["HotFix_Project.Lesson3_Test"];
    object obj = ((ILType)type).Instantiate();
    print(obj);
    obj = ((ILType)type).Instantiate(new object[] { "234" });
    print(obj);
    });
    }
  • 方式三:通过方式二中得到的IType​对象,再去得到它的构造函数进行实例化,该方式类似反射

    这里更多的是通过IType.ReflectionType​获取Type​,再反射出的构造函数的消息,然后反射出的构造函数消息实例化出对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void Start()
    {
    ILRuntimeMgr.Instance.StartILRuntime(() =>
    {
    IType type = appDomain.LoadedTypes["HotFix_Project.Lesson3_Test"];
    ConstructorInfo info = type.ReflectionType.GetConstructor(new System.Type[0]);
    obj = info.Invoke(null);
    print(obj);
    info = type.ReflectionType.GetConstructor(new System.Type[] { typeof(string) });
    obj = info.Invoke(new object[] { "345" });
    print(obj);
    });
    }