Unity-C# MVC模式下Service类集合的通用获取器实现问询
嘿,这个需求完全贴合Unity MVC架构的实用场景啊,我来给你一套落地性拉满的实现方案:
1. 先完善Service抽象类的基础实现
先把你提到的ServiceAbstract补全,它要持有App实例的引用,构造函数传入App确保子类能访问核心上下文:
public abstract class ServiceAbstract { // 只读的App实例引用,子类可以直接调用 protected App AppInstance { get; } protected ServiceAbstract(App app) { AppInstance = app ?? throw new ArgumentNullException(nameof(app), "App实例不能为null"); } // 可选:给子类加一个初始化钩子,App创建Service后统一触发 public virtual void Initialize() { } }
2. 实现App类的Service容器与通用获取器
App类里用Dictionary<Type, ServiceAbstract>作为容器存储所有Service,同时负责统一创建这些Service,再写一个泛型方法做类型安全的通用获取:
public class App : MonoBehaviour { // Unity常用单例模式,方便全局访问(不需要的话可以去掉) public static App Instance { get; private set; } // Service容器:用Type作为键,确保每个Service类型唯一 private Dictionary<Type, ServiceAbstract> _serviceContainer = new Dictionary<Type, ServiceAbstract>(); private void Awake() { // 单例初始化逻辑(可选) if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; DontDestroyOnLoad(gameObject); // 在这里创建并注册所有业务Service InitializeServices(); } private void InitializeServices() { // 创建具体Service实例,传入当前App实例 RegisterService(new UserService(this)); RegisterService(new GameDataService(this)); RegisterService(new AudioService(this)); // 统一调用所有Service的初始化方法(如果有) foreach (var service in _serviceContainer.Values) { service.Initialize(); } } // 内部注册方法,避免重复注册同一类型Service private void RegisterService(ServiceAbstract service) { Type serviceType = service.GetType(); if (_serviceContainer.ContainsKey(serviceType)) { Debug.LogWarning($"Service类型 {serviceType.Name} 已存在,跳过重复注册"); return; } _serviceContainer.Add(serviceType, service); } // 通用获取器:泛型方法确保类型安全,避免强制转换 public T GetService<T>() where T : ServiceAbstract { if (_serviceContainer.TryGetValue(typeof(T), out var service)) { return service as T; } // 这里可以根据需求选择抛出异常或返回null throw new InvalidOperationException($"未找到类型为 {typeof(T).Name} 的Service,请先在App中注册"); // 或者 return null; } }
3. 编写具体的业务Service子类
比如一个处理用户数据的Service示例:
public class UserService : ServiceAbstract { public UserService(App app) : base(app) { } // 重写初始化方法做业务初始化(可选) public override void Initialize() { // 可以通过AppInstance访问其他Service或App全局数据 var gameDataService = AppInstance.GetService<GameDataService>(); LoadLocalUserProfile(); } public void LoadLocalUserProfile() { // 具体业务逻辑:比如读取本地存档、同步云端数据等 } }
4. 在Unity业务代码中使用
比如在MVC的Controller里获取Service:
public class UserController : MonoBehaviour { private UserService _userService; private void Start() { // 通过App单例快速获取目标Service _userService = App.Instance.GetService<UserService>(); _userService.LoadLocalUserProfile(); } }
这个方案的优势:
- 完全匹配你的需求:App统一创建、管理Service,容器存储+泛型通用获取器
- 扩展性极强:新增Service只需继承
ServiceAbstract,在App的InitializeServices里注册即可 - 类型安全:泛型获取器避免了强制转换的风险,编译期就能发现类型错误
- 适配Unity生命周期:利用
Awake做初始化,单例模式确保全局唯一
内容的提问来源于stack exchange,提问作者Jobbo
相关产品推荐
相关产品推荐

