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;
        }
    }
}

源码下载

相关推荐
赵庆明老师17 分钟前
NET 10 中DLL,并发布到NuGet
服务器·c#·.net
赵庆明老师27 分钟前
.net framework 的项目部署到docker
docker·eureka·.net
赵庆明老师40 分钟前
用缓存功能解决.NET程序访问数据库的性能问题
数据库·缓存·.net
时光追逐者42 分钟前
排查 EF 保存数据时提示:Validation failed for one or more entities 的问题
数据库·c#·.net·ef
时光追逐者1 小时前
在 .NET 中将 EF Core 升级到 9.0.5 MySQL 连接提示 get_LockReleaseBehavior
数据库·mysql·c#·.net·ef core
唐青枫1 小时前
LINQ 新时代:CountBy、AggregateBy 深度解析(含对比 GroupBy)
c#·.net
CodeCraft Studio9 小时前
文档开发组件Aspose 25.12全新发布:多模块更新,继续强化文档、图像与演示处理能力
前端·.net·ppt·aspose·文档转换·word文档开发·文档开发api
追逐时光者10 小时前
一款开源、现代化的 WinForm UI 控件库
后端·.net
SEO-狼术21 小时前
TeamCity 2025.11 offers Crack
.net
小码编匠1 天前
WPF 实现高仿 Windows 通知提示框:工业级弹窗设计与实现
后端·c#·.net