8 24 81

.Net 手写简易依赖注入容器

    相信大部分人都用过.Net依赖注入容器,但可能只会使用不了解其原理,之前通过Rider这个IDE了解过.net core 依赖注入容器大致原理。

打算自己去实现一个简单的容器加深理解。

    


  依赖注入对象有三种生命周期:

  1、Transient

  2、Scope

  3、Singeton

 要如何实现这三种方式呢

一开始我们要注册对象并指定生命周期,那么如何保存这些注入的对象类型呢,用根据不同生命周期去保存:

 private static Dictionary<string, (LifeTime, Type)> types = new Dictionary<string, (LifeTime, Type)>();
 private static Dictionary<string, object> SingletonObjs = new Dictionary<string, object>();

这里的LifeTime就是定义生命周期的枚举:

  public enum LifeTime
    {
        Transient,

        Scope,

        Singleton
    }

然后singletonObjs是单例模式下保存的对象,当有用到的时候从里面取出对象即可,那么注册对象就是向types 字典放入对象,很简单就可以理解:

复制代码
        /// <summary>
        /// transient
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <typeparam name="TTo"></typeparam>
        public static void RegisterTransientType<TFrom, TTo>() where TTo : TFrom
        {
            types.Add(typeof(TFrom).FullName, (LifeTime.Transient, typeof(TTo)));
        }

        /// <summary>
        /// Scope
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <typeparam name="TTo"></typeparam>
        public static void RegisterScopeType<TFrom, TTo>() where TTo : TFrom
        {
            types.Add(typeof(TFrom).FullName, (LifeTime.Transient, typeof(TTo)));
        }
    

        /// <summary>
        /// Singleton
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <typeparam name="TTo"></typeparam>
        public static void RegisterSingletonType<TFrom, TTo>() where TTo : TFrom
        {
            types.Add(typeof(TFrom).FullName, (LifeTime.Singleton, typeof(TTo)));
            Type type = typeof(TTo);
            var obj = Resolve<TFrom>(type);
            SingletonObjs.Add(typeof(TFrom).FullName, obj);
        }    
复制代码

 注册完对象就可以使用了,下面是获取对象的方法。当然这里只是举一个简单的例子,.Net依赖注入容器是非常强大的,不能混为一谈。

复制代码
        public static T Resolve<T>()
        {
            if (!types.ContainsKey(typeof(T).FullName))
                return default;
            var obj = types[typeof(T).FullName];
            Type type = obj.Item2;
            if (obj.Item1 == LifeTime.Singleton)
            {
                if (SingletonObjs.ContainsKey(typeof(T).FullName))
                {
                    var result = SingletonObjs[typeof(T).FullName];
                    if (result is T)
                    {
                        return (T)result;
                    }
                }
                else
                {
                    return default;
                }
            }

            return Resolve<T>(type);
        }

        public static T Resolve<T>(Type type)
        {
            //首先获取构造函数的type
            var constructorInfos = type.GetConstructors();
            List<object> list = new List<object>();
            foreach (var ctor in constructorInfos)
            {
                foreach (var item in ctor.GetParameters())
                {
                    var itemType = item.ParameterType;
                    var itemTargeType = types[itemType.FullName].Item2;
                    var target = Resolve<object>(itemTargeType);
                    list.Add(target);
                }
            }
            T t = default(T);
            t = (T)Activator.CreateInstance(type, list.ToArray());

            return t;
        }
复制代码

通过Resolve达到注册的目的,例子演示:

复制代码
先注册:           
RegisterSingletonType<ISortService, SortService>(); 然后获取: private readonly ISortService sortService; public TestController() { sortService = DependencyInjectionContainer.Resolve<ISortService>(); }
复制代码

这里要说明一下,这里和.Net 依赖注入还是有所区别的,这里没有构造注入,而且.Net的scope是和请求的Context绑定以达到scope注入的目的的。

通过实现简易IOC,更加加深了IOC设计原则的理解,希望大家也能有所提高。

posted @   Ivan_Ivan  阅读(244)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示