文章目录
Unity C# 使用微软 DependencyInjection 库实现依赖注入实验
🍀 引言:😋
🍀 上一篇文章写(chao)了unity C# 的简单反射框架
🍀 经过一段时间的.net学习后,本菜鸟接触到了.net常用的反射依赖框架Microsoft.Extensions.DependencyInjection
🍀 遂突发奇想,想借助该框架在unity中实现简单的依赖倒转,减少singleton和monobehavior的使用频率
🍀 但是由于性能关系,暂时不准备将反射和依赖注入结合,以实现类似于spring的@Autowire
的注入方式(使用反射实例化类的速度,是正常实例化的20倍,更何况检查程序集,这对本就性能不佳的unity中更是雪上加霜)
🍀 代码来源:原创(骄傲)
🍀 目的:检验Microsoft.Extensions.DependencyInjection
在unity中使用的可行性;练习DependencyInjection
的基本使用;使用该库搭建框架以减少《游戏设计模式》中不推荐的singleton的使用频率,顺带尝试减少MonoBehavior的使用频率
环境准备
开发环境
- unity 2022.3.8f1c1
- jetbrains rider 2023.2.1
依赖的库准备
NugetForUnity
- 按照文章后面的地址下载该库并导入
Microsoft.Extensions.DependencyInjection
项目结构
代码
SingletonBaseMonoBehaviorWithoutLifeCycle
- 提供挂载的单例基类
using UnityEngine;
namespace CattailFramework.DesignPatterns
{
public class SingletonBaseMonoBehaviorWithoutLifeCycle<T> : MonoBehaviour
where T : Component
{
private static T _instance;
private static readonly object _lock = new();
public static T Instance
{
get
{
if (_instance is not null) return _instance;
lock (_lock)
{
if (_instance is null) _instance = FindObjectOfType<T>();
}
return _instance;
}
set => _instance = value;
}
}
}
Model
- 提供数据
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace CattailFramework.DependencyInjection.Test
{
public class Model : MonoBehaviour
{
public string str = "test success!";
}
}
IController
- 提供访问接口
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace CattailFramework.DependencyInjection.Test
{
public interface IController
{
string GetModelStr();
}
}
Controller
- 控制类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using CattailFramework.DependencyInjection.Test;
public class Controller: IController
{
private Model _model;
public Controller(Model model)
{
_model = model;
}
public string GetModelStr()
{
return _model.str;
}
}
DependencyInjectionManager
- 实现依赖倒转功能
- 实现类的注册
- 全局提供访问点
using System;
using CattailFramework.DesignPatterns;
using Microsoft.Extensions.DependencyInjection;
using CattailFramework.DependencyInjection.Test;
namespace CattailFramework.DependencyInjection
{
public class DependencyInjectionManager : SingletonBaseMonoBehaviorWithoutLifeCycle<DependencyInjectionManager>
{
private ServiceCollection _serviceCollection = new ServiceCollection();
public ServiceProvider ServiceProvider;
public DependencyInjectionManager()
{
_serviceCollection.AddSingleton<IController, Controller>();
_serviceCollection.AddSingleton<Model>();
}
private void Awake()
{
ServiceProvider = _serviceCollection.BuildServiceProvider();
}
}
}
- 注意:只要把该脚本的实现时机设置为最先,就能避免Awake冲突
Viewer
- 获取依赖倒转容器中的对象
- 通过该对象获取数据
- 并显示在屏幕上
using System;
using CattailFramework.DependencyInjection;
using CattailFramework.DependencyInjection.Test;
using Microsoft.Extensions.DependencyInjection;
using TMPro;
using UnityEngine;
public class Viewer : MonoBehaviour
{
private IController _controller;
private TextMeshProUGUI _text;
private void Awake()
{
_text = GetComponent<TextMeshProUGUI>();
}
private void Start()
{
_controller = DependencyInjectionManager.Instance.ServiceProvider.GetService<IController>();
Debug.Log(_controller.GetModelStr());
_text.text = _controller.GetModelStr(); // 用于在导出游戏项目后验证该框架的可用性
}
}
测试
editor 测试环境搭建
测试结果
editor运行结果
导出游戏项目运行结果
总结
- 验证了Microsoft.Extensions.DependencyInjection库在unity中使用的可行性
- 练习了DependencyInjection库的基本使用
- 为游戏框架开发提供支撑
相关链接
【Unity Code】Unity C# 反射帮助框架-CSDN博客
声明
- 本博客是新手小白的学习博客,仅供参考,如侵权请联系作者调整或删除。
- 欢迎大佬不吝赐教,加以斧正。
参考资料
GlitchEnzo/NuGetForUnity: A NuGet Package Manager for Unity (github.com)