侧边栏壁纸
博主头像
进击的码农博主等级

新年新气象,开搞开搞

  • 累计撰写 31 篇文章
  • 累计创建 11 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

依赖注入的容器是什么

wosperry
2021-11-21 / 0 评论 / 0 点赞 / 4 阅读 / 4921 字

容器简单实现

控制台程序

programl.cs


Console.WriteLine("程序开始");

// 原理:字典
DictionaryDemo.StringDictionary();
Console.WriteLine("______________________");

// NetCore自带的容器
DictionaryDemo.ServiceCollectionDemo();
Console.WriteLine("______________________");

// 模仿NetCore自带容器的字典容器实现
DictionaryDemo.TypeDictionary();

Console.WriteLine("程序结束");


容器的原理

namespace DIDemo
{
    public static class DictionaryDemo
    {
        /// <summary>
        /// 原理描述:字符串字典
        /// </summary>
        public static void StringDictionary()
        {
            // 定义一个字典
            var services = new Dictionary<string, string>();

            // 注册服务:添加键值对到字典中放着
            services.Add("IUserService", "UserService");
            services.Add("IStudentService", "StudentService");
            services.Add("IBookService", "BookService");

            // 获取服务:根据Key从字典中获取到想要的类型
            var service = services["IUserService"];

            // 使用
            Console.WriteLine(service);
        }
    }
}

dotnet 自带容器演示

namespace DIDemo
{
    public static class DictionaryDemo
    {
        /// <summary>
        /// Dotnet自带容器演示
        /// </summary>
        public static void ServiceCollectionDemo()
        {
            // 定义一个字典
            var services = new ServiceCollection();

            // 注册服务:添加键值对到字典中放着
            services.AddTransient<ITestService, TestService>();
            services.AddTransient<IUserService, UserService>();
            services.AddTransient<ITest001Service, Test001Service>();

            // 创建一个服务提供器
            var povider = services.BuildServiceProvider();
            // 获取服务:根据Key从字典中获取到想要的类型
            var service = povider.GetService<ITestService>();

            // 使用
            Console.WriteLine(service.Get());
        }
    }
}

参考自带容器功能自己用Dictionary实现一个简单的容器(不带生命周期控制)


namespace DIDemo
{
    public static class DictionaryDemo
    {
        /// <summary>
        /// 使用字典实现一个最简单的不带生命周期控制的容器
        /// </summary>
        public static void TypeDictionary()
        {
            // 定义一个字典
            var services = new Dictionary<Type, Type>();

            // 注册服务:添加键值对到字典中放着
            services.AddTransient<ITestService, TestService>();
            services.AddTransient<IUserService, UserService>();
            services.AddTransient<ITest001Service, Test001Service>();

            // 获取服务:根据Key从字典中获取到想要的类型
            var service = services.GetService<ITestService>();
            // 使用
            Console.WriteLine(service.Get());
        }

        /// <summary>
        /// 构建对象逻辑代码
        /// </summary>
        /// <param name="services">容器</param>
        /// <param name="interfaceType">接口类型</param>
        /// <returns>object类型的对象</returns>
        public static object GetService(Dictionary<Type, Type> services, Type interfaceType)
        {
            if (services.ContainsKey(interfaceType))
            {
                Type implementType = services[interfaceType];
                // 获取构造函数
                var ctor = implementType
                    // 所有的构造函数
                    .GetConstructors()
                    // 参数最多的拿出来
                    .OrderByDescending(t => t.GetParameters().Count()).FirstOrDefault();

                if (ctor is not null)
                {
                    // 调用的时候发现有参数
                    var parameterTypes = ctor.GetParameters().Select(t => t.ParameterType);
                    List<object> pList = new List<object>();
                    // 每一个参数类型,构造
                    foreach (var pType in parameterTypes)
                    {
                        var p = GetService(services, pType);
                        if (p is not null)
                        {
                            pList.Add(p);
                        }
                    }

                    return ctor.Invoke(pList.ToArray());
                }
            }

            return default!;
        }

        /// <summary>
        /// 包个好用点的拓展方法
        /// </summary>
        public static Dictionary<Type, Type> AddTransient<TInterface, TImplement>(this Dictionary<Type, Type> services)
        {
            services.Add(typeof(TInterface), typeof(TImplement));
            return services;
        }

        /// <summary>
        /// 包一个好用点的拓展方法
        /// </summary>
        public static TInterface GetService<TInterface>(this Dictionary<Type, Type> services)
        {
            return (TInterface)GetService(services, typeof(ITestService));
        }
    }
}

0

评论区