IOC、DI<3> IServiceConllection 自定义IOC含属性注入、多实现注入,方法注入



csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace IOC.Common
{
    public class ZenServiceCollection : IZenServiceCollection
    {
        // 记录IOC注册的抽象、实现
        private Dictionary<string, Type> zenRelationship = new Dictionary<string, Type>();
        /// <summary>
        /// IOC容器映射关系注册   ===》  抽象 和具体
        /// </summary>
        /// <param name="serviceType">具体类</param>
        /// <param name="implementtationType">实现类</param>
        public void AddTransient(Type serviceType, Type implementtationType)
        {
            this.zenRelationship.Add(serviceType.FullName, implementtationType);
        }
        /// <summary>
        /// 获取服务
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetService<T>()
        {
            {
                //只限有无参构造函数, 若类没有构造函数,ctr会自动生成一个无参构造函数,但若定义了有参构造函数,就不会自动创建无参构造函数啦
                //Type t = zenRelationship[typeof(T).FullName];
                //return (T)Activator.CreateInstance(t);
            }
            {
                继续迭代 支持有参构造函数 ,只支持1个层级的有参构造函数  
                //Type t = zenRelationship[typeof(T).FullName];
                确定构造当前对象使用哪个构造函数(默认选择参数最多的构造函数)
                //ConstructorInfo[] ctors = t.GetConstructors();
                //ConstructorInfo ctor = ctors.OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();
                //List<object> paralist = new List<object>();
                //foreach (ParameterInfo item in ctor.GetParameters())
                //{
                //    Type tt = item.ParameterType;
                //    Type ttt = item.GetType();
                //    Type t1 = zenRelationship[item.ParameterType.FullName];
                //    var target = Activator.CreateInstance(t1);
                //    paralist.Add(target);
                //}
                //return (T)Activator.CreateInstance(t, paralist.ToArray());
            }
            {
                继续迭代 支持有参构造函数   无线层级的
                //Type t = zenRelationship[typeof(T).FullName];
                //return (T)this.GetService(t);               
            }
            {
                //利用特性 指明构造函数创建  ,  默认是  使用 参数最多
                Type t = zenRelationship[typeof(T).FullName];
                return (T)this.GetService(t);
            }
        }

        private object GetService(Type type)
        {
            #region 构造函数注入
            ConstructorInfo[] ctors = type.GetConstructors();
            ConstructorInfo ctor = ctors.Where(c=>c.IsDefined(typeof(SelectConstructAttribute),true)).FirstOrDefault();
            if (ctor==null)
            {
                //当ctor不存在,则表示 构造函数没有对应特性标识
                ctor= ctors.OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();
            }
            List<object> paralist = new List<object>();            
            foreach (ParameterInfo item in ctor.GetParameters())
            {
                Type t1 = zenRelationship[item.ParameterType.FullName];
                var target=this.GetService(t1);               
                paralist.Add(target);
            }
            #region  方法注入
            //构造对象
            object objInstance = Activator.CreateInstance(type, paralist.ToArray());           
            //获取对象的属性  只获取含有特性PropertyInjectionAttribute的属性
            foreach (MethodInfo item in type.GetMethods().Where(c => c.IsDefined(typeof(MethodInjectionAttribute), true)))
            {
                List<object> paraOfMethodlist = new List<object>();
                foreach (ParameterInfo para in item.GetParameters())
                {
                    Type t1 = zenRelationship[para.ParameterType.FullName];
                    var target = this.GetService(t1);
                    paraOfMethodlist.Add(target);
                }
                item.Invoke(objInstance, paraOfMethodlist.ToArray());
            }
            #endregion
            #endregion
            #region  属性注入           
            //获取对象的属性  只获取含有特性PropertyInjectionAttribute的属性
            foreach (PropertyInfo item in type.GetProperties().Where(c=>c.IsDefined(typeof(PropertyInjectionAttribute),true)))
            {
                Type t1 = zenRelationship[item.PropertyType.FullName];
                var target = this.GetService(t1);
                item.SetValue(objInstance,target);
            }
            #endregion
            return objInstance;
        }
    }
}

源码下载

相关推荐
Cincoze-Johnny5 小时前
Windows系统-应用问题全面剖析Ⅴ:德承工控机DA-1000在Windows操作系统下[安装.NET Framework]教程
.net
黑夜中的潜行者10 小时前
构建高性能 WPF 大图浏览器:TiledViewer 技术解密
性能优化·c#·.net·wpf·图形渲染
初九之潜龙勿用13 小时前
C#实现导出Word图表通用方法之散点图
开发语言·c#·word·.net·office·图表
明月看潮生14 小时前
编程与数学 03-008 《看潮企业管理软件》项目开发 01 需求分析 3-1
c#·.net·需求分析·erp·企业开发·项目实践·编程与数学
步步为营DotNet15 小时前
深度钻研.NET 中Task.Run:异步任务执行的便捷入口
java·服务器·.net
云草桑15 小时前
在C# .net中RabbitMQ的核心类型和属性,除了交换机,队列关键的类型 / 属性,影响其行为
c#·rabbitmq·.net·队列
jackletter1 天前
3dsmax2026插件开发入门:使用.net8开发
.net·3dmax·入门·插件·.net8·3dsmax2026
1314lay_10071 天前
.NET 7.0在.NET Core Web API中实现限流
.net·.netcore
步步为营DotNet1 天前
深入探究.NET中Stream:灵活高效的数据流处理核心
服务器·数据库·.net
1314lay_10071 天前
C# .Net 7.0 Core添加日志可视化
visualstudio·c#·.net·.netcore