4.Unity实例化ILR对象

4.Unity调用ILRuntime-实例化对象


4.1 知识点

在ILRuntime热更工程中新建一个类,给类并添加两个构造函数

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HotFix_Project
{
    class Lesson4_Test
    {
        public string str;
        public Lesson4_Test()
        {

        }

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

在Unity中跨域调用ILRuntime中的类

需要让ILRuntime重新生成最新的dll和pdb文件,右键重新生成热更工程,这样会更新StreamAsset下的dll文件和pdb文件

AppDomain.Instantiate 实例化ILRuntime中的对象

AppDomain.LoadedTypes 得到ILRuntime中的对象的IType

ITyp.Instantiate 实例化ILRuntime中的对象

IType.ReflectionType.GetConstructor.Invoke 实例化ILRuntime中的对象

//需要让ILRuntime重新生成最新的dll和pdb文件

ILRuntimeManager.Instance.StartILRuntime(() =>
{
    //这里面做的事情 是在加载完了dll和pdb文件后做的
    
    
    // 得到appDomain单例
    ILRuntime.Runtime.Enviorment.AppDomain appDomain = ILRuntimeManager.Instance.appDomain;
    
    
    
    
    //AppDomain.Instantiate 传入HotFix_Project.类名实例化对象
    //方式一:appdomain中的Instantiate方法
    //       参数一:类的命名空间.类名
    //       参数二:参数列表
    object obj = appDomain.Instantiate("HotFix_Project.Lesson4_Test");
    // 注意我们是不能用Lesson4_Test来装返回的对象的 因为ILRuntime底层用自定义的类表示热更的类 实例化的类其实不是Lesson4_Test了
    print(obj);//HotFix_Project.Lesson4_Test
    // 有参构造,传入object数组,数组元素作为参数
    obj = appDomain.Instantiate("HotFix_Project.Lesson4_Test", new object[] { "123" });
    print(obj);//HotFix_Project.Lesson4_Test
    
    
    //AppDomain.LoadedTypes字典 传入HotFix_Project.类名作为键得到IType值进行实例化
    //方式二:appdomain中LoadedTypes字典获取IType类型后,强转为ILType后调用Instantiate方法
    //       该方式类似反射
    IType type = appDomain.LoadedTypes["HotFix_Project.Lesson4_Test"];
    //IType强转成ILType再进行Instantiate实例化
    obj = ((ILType)type).Instantiate();
    print(obj);//HotFix_Project.Lesson4_Test
    // 有参构造,传入object数组,数组元素作为参数
    obj = ((ILType)type).Instantiate(new object[] { "234" });
    print(obj);//HotFix_Project.Lesson4_Test
    
    
    //IType.ReflectionType.GetConstructor 得到IType的构造函数信息进行实例化
    //方式三:通过方式二中得到的IType对象,再去得到它的构造函数进行实例化
    //       该方式类似反射
    ConstructorInfo info = type.ReflectionType.GetConstructor(new Type[0]);
    //info.Invoke 无参不用传参
    obj = info.Invoke(null);
    print(obj);//HotFix_Project.Lesson4_Test
    // 传入object数组得到有参构造函数信息
    info = type.ReflectionType.GetConstructor(new Type[] { typeof(string) });
    // 使用有参构造,传入object数组,数组元素作为参数
    obj = info.Invoke(new object[] { "11111" });
    print(obj);//HotFix_Project.Lesson4_Test


    //综合来说,更推荐方式2,因为之后在调用对象方法变量时,通过方式2更方便
});

总结

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

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

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


4.2 知识点代码

Lesson4_Test

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HotFix_Project
{
    class Lesson4_Test
    {
        public string str;
        public Lesson4_Test()
        {

        }

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

Lesson04_Unity调用ILRuntime_实例化对象

using ILRuntime.CLR.TypeSystem;
using ILRuntime.Runtime.Enviorment;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using BaseFramework;
using UnityEngine;

public class Lesson04_Unity调用ILRuntime_实例化对象 : MonoBehaviour
{
    void Start()
    {
        #region 知识点一 在ILRuntime热更工程中新建一个类

        //只需要在ILRuntime的工程中新建一个类即可
        //并为该类声明几个构造函数重载

        #endregion

        #region 知识点二 在Unity中跨域调用ILRuntime中的类

        //需要让ILRuntime重新生成最新的dll和pdb文件

        ILRuntimeManager.Instance.StartILRuntime(() =>
        {
            //这里面做的事情 是在加载完了dll和pdb文件后做的
            
            
            // 得到appDomain单例
            ILRuntime.Runtime.Enviorment.AppDomain appDomain = ILRuntimeManager.Instance.appDomain;
            
            
            
            //AppDomain.Instantiate 传入HotFix_Project.类名实例化对象
            //方式一:appdomain中的Instantiate方法
            //       参数一:类的命名空间.类名
            //       参数二:参数列表
            object obj = appDomain.Instantiate("HotFix_Project.Lesson4_Test");
            // 注意我们是不能用Lesson4_Test来装返回的对象的 因为ILRuntime底层用自定义的类表示热更的类 实例化的类其实不是Lesson4_Test了
            print(obj);//HotFix_Project.Lesson4_Test
            // 有参构造,传入object数组,数组元素作为参数
            obj = appDomain.Instantiate("HotFix_Project.Lesson4_Test", new object[] { "123" });
            print(obj);//HotFix_Project.Lesson4_Test

            
            
            //AppDomain.LoadedTypes字典 传入HotFix_Project.类名作为键得到IType值进行实例化
            //方式二:appdomain中LoadedTypes字典获取IType类型后,强转为ILType后调用Instantiate方法
            //       该方式类似反射
            IType type = appDomain.LoadedTypes["HotFix_Project.Lesson4_Test"];
            //IType强转成ILType再进行Instantiate实例化
            obj = ((ILType)type).Instantiate();
            print(obj);//HotFix_Project.Lesson4_Test
            // 有参构造,传入object数组,数组元素作为参数
            obj = ((ILType)type).Instantiate(new object[] { "234" });
            print(obj);//HotFix_Project.Lesson4_Test

            
            
            //IType.ReflectionType.GetConstructor 得到IType的构造函数信息进行实例化
            //方式三:通过方式二中得到的IType对象,再去得到它的构造函数进行实例化
            //       该方式类似反射
            ConstructorInfo info = type.ReflectionType.GetConstructor(new Type[0]);
            //info.Invoke 无参不用传参
            obj = info.Invoke(null);
            print(obj);//HotFix_Project.Lesson4_Test
            // 传入object数组得到有参构造函数信息
            info = type.ReflectionType.GetConstructor(new Type[] { typeof(string) });
            // 使用有参构造,传入object数组,数组元素作为参数
            obj = info.Invoke(new object[] { "11111" });
            print(obj);//HotFix_Project.Lesson4_Test


            //综合来说,更推荐方式2,因为之后在调用对象方法变量时,通过方式2更方便
        });

        #endregion

        #region 总结

        //Unity中实例化ILRuntime中类对象主要有三种方式
        //1.appdomain中的Instantiate方法
        //2.appdomain中LoadedTypes字典获取IType类型后, 强转为ILType后调用Instantiate方法
        //3.appdomain中LoadedTypes字典获取IType类型后, 再去获取它的构造函数信息用于实例化对象

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

        #endregion
    }
}

4.3 练习题

练习一下Unity跨域实例化ILRuntime中的类对象



转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏