IOC容器代码设计 4

using System;
using System.Collections.Generic;
using UnityEngine;
public class IOCContainer
{
    //创建字典存储实例
    private Dictionary<Type, object> m_instances = new Dictionary<Type, object>();

    public void RegisterInstance<T>(T instance)
    {
        //反射获取类信息
        var type = typeof(T);
        //判断是否存在
        if (m_instances.ContainsKey(type))
        {   //如果存在,则替换
            m_instances[type] = instance;
        }
        else
        {   //不存在,则添加
            m_instances.Add(type, instance);
        }
    }

    public T Get<T>() where T : class
    {   //获取实例
        var key = typeof(T);
        //out 存储
        object retInstance;
        //判断是否存在
        if (m_instances.TryGetValue(key,out retInstance))
        {
            //存在,则直接返回
            return retInstance as T;
        }
        //不存在  抛出异常
        Debug.LogError("IOCContainer:未包括实例" + typeof(T).Name);
        return null;
    }
}
===============================================================================
using UnityEngine;
public abstract class Architecture<T> where T : Architecture<T>, new()
{
    public static T mArchitecture;

    // 确保 Container 是有实例的
    static void MakesureArchitecture()
    {
        if (mArchitecture == null)
        {
            mArchitecture = new T();
            mArchitecture.Init();
        }
    }

    //留给子类注册模块
    protected abstract void Init();

    // 提供一个注册模块的 API
    public void Register<T>(T instance)
    {
        MakesureArchitecture();
        mArchitecture.mIOCContainer.RegisterInstance<T>(instance);//注册进IOC容器
    }
    private IOCContainer mIOCContainer = new IOCContainer();

    // 提供一个获取模块的 API
    public static T Get<T>() where T : class
    { 
        MakesureArchitecture();
        return mArchitecture.mIOCContainer.Get<T>();//从IOC容器获取实例
    } 
}
=====================================================================================
这里我们创建一个 DIPExample.cs 脚本,DIP 是依赖倒置原则的意思,代码如下:
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
    public class DIPExample : MonoBehaviour
    {
        // 1. 设计模块接口
        public interface IStorage
        {
            void SaveString(string key, string value);
            string LoadString(string key, string defaultValue = "");
        }

        // 2. 实现接口
        // 运行时存储
        public class PlayerPrefsStorage : IStorage
        {
            public void SaveString(string key, string value)
            {
                PlayerPrefs.SetString(key, value);
            }

            public string LoadString(string key, string defaultValue = "")
            {
                return PlayerPrefs.GetString(key, defaultValue);
            }
        }

        // 3. 实现接口
        // 编辑器存储
        public class EditorPrefsStorage : IStorage
        {
            public void SaveString(string key, string value)
            {
#if UNITY_EDITOR
                EditorPrefs.SetString(key, value);
#endif
            }

            public string LoadString(string key, string defaultValue = "")
            {
#if UNITY_EDITOR
                return EditorPrefs.GetString(key, defaultValue);
#else
                return ""
#endif
            }
        }
        // 4. 使用
        private void Start()
        {
            // 创建一个 IOC 容器
            var container = new IOCContainer();

            // 注册运行时模块
            container.Register<IStorage>(new PlayerPrefsStorage());

            var storage = container.Get<IStorage>();
            
            storage.SaveString("name", "运行时存储");

            Debug.Log(storage.LoadString("name"));
            
            // 切换实现
            container.Register<IStorage>(new EditorPrefsStorage());

            storage = container.Get<IStorage>();
            
            Debug.Log(storage.LoadString("name"));
        }
    }
}
不管是模块的设计过程,还是切换实现,还是解耦这个示例都有所体现。
======================================================================================
还可以增加单个容器保存多个接口
public class IOCContainer
{
    // 使用 Dictionary 存储接口到其实现列表的映射
    private readonly Dictionary<Type, List<(string, object)> mInstances = new Dictionary<Type, List<(string, object)>>();

    public void Register<T>(string name, T instance) where T : class
    {
        if (!mInstances.ContainsKey(typeof(T)))
        {
            mInstances[typeof(T)] = new List<(string, object)>();
        }
        mInstances[typeof(T)].Add((name, instance));
    }

    public T Get<T>(string name) where T : class
    {
        if (mInstances.TryGetValue(typeof(T), out var instances))
        {
            foreach (var (n, instance) in instances)
            {
                if (n == name)
                    return instance as T;
            }
        }
         //不存在  抛出异常
        Debug.LogError("IOCContainer:未包括实例" + typeof(T).Name);
        return null;
    }
}
=====================================================================================
container.Register<IGameManager>("V1", new SoundManagerV1());
container.Register<IGameManager>("V2", new SoundManagerV2());

var v1Manager = container.Get<IGameManager>("V1");
v1Manager.Connect(); // 连接,这里假设V1的实现会打印"V1连接成功"

var v2Manager = container.Get<IGameManager>("V2");
v2Manager.Connect(); // 连接,这里假设V2的实现会打印"V2连接成功"
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值