首页 > 其他分享 >IOC控制反转,DI依赖注入,自定义IOC及生命周期,反射

IOC控制反转,DI依赖注入,自定义IOC及生命周期,反射

时间:2022-09-25 22:35:50浏览次数:52  
标签:自定义 DI IOC typeof type ZXInjectionConstructor ctor 构造函数

//1.依赖倒置原则
//2.IOC控制反转
//3.DI依赖注入
//4.Unity容器
//5.自定义IOC容器

IOC: 依赖抽象,不依赖细节,控制反转
IOC:工厂
DI:实现方式 依赖导致原则

 

1.创建容器,
2.指定注册关系:构造函数注入
3.生成对象
4.IOC生命周期管理:
默认是瞬时生命周期
单例模式:是同一个应用
线程单例:同一个线程是同一个实列

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ZXFramework.Common
{
public class ZXContainer : IZXContainer
{
private Dictionary<string, Type> ZXContainerDicationary = new Dictionary<string, Type>();
public void RegisterType<TFrom, TTo>() where TTo : TFrom
{
ZXContainerDicationary.Add(typeof(TFrom).FullName, typeof(TTo));
}

/// <summary>
/// T:是一个抽象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Resolve<T>()
{
#region MyRegion
//string abstartName = typeof(T).FullName;
//Type type = ZXContainerDicationary[abstartName];
////怎么解决?
////1.先准备参数; 传递过去;
////2.确定执行哪个构造函数;---如果没有标记[InjectionConstructor];默认规则;选择参数最多的构造函数---如果标记[InjectionConstructor]特性---执行标记特性的这个构造函数
////3.确定要执行的构造函数参数的类型
////4.通过构造函数参数的类型得到具体的类型
////5.创建该类型的对象
////6.当做参数传递过去
//ConstructorInfo ctor = null;
////如果有ZXInjectionConstructor,就找出标记的有ZXInjectionConstructor特性的构造函数
//if (type.GetConstructors().Count(c => c.IsDefined(typeof(ZXInjectionConstructor), true)) > 0)
//{
// ctor = type.GetConstructors().FirstOrDefault(c => c.IsDefined(typeof(ZXInjectionConstructor), true));
//}
//else
//{
// ctor = type.GetConstructors().OrderByDescending(c => c.GetParameters().Length).First();
//}

//List<object> parameterlist = new List<object>();
//foreach (ParameterInfo parameter in ctor.GetParameters())
//{
// string parameterType = parameter.ParameterType.FullName;
// Type targetType = ZXContainerDicationary[parameterType];

// //1.先准备参数; 传递过去;
// //2.确定执行哪个构造函数;---如果没有标记[InjectionConstructor];默认规则;选择参数最多的构造函数---如果标记[InjectionConstructor]特性---执行标记特性的这个构造函数
// //3.确定要执行的构造函数参数的类型
// //4.通过构造函数参数的类型得到具体的类型
// //5.创建该类型的对象
// //6.当做参数传递过去
// object oParameter = Activator.CreateInstance(targetType);
// parameterlist.Add(oParameter);
//}
//object oInstance = Activator.CreateInstance(type, parameterlist.ToArray());//调用的五参数构造函数;//如果有两级依赖
//return (T)oInstance;
#endregion

string abstartName = typeof(T).FullName;
Type type = ZXContainerDicationary[abstartName];
return (T)this.ObjectInstance(type);
}

//不知道层级---且实现都是统一的=====递归的;

//递归一定是要有跳出条件的;

private object ObjectInstance(Type type)
{
ConstructorInfo ctor = null;
//如果有ZXInjectionConstructor,就找出标记的有ZXInjectionConstructor特性的构造函数
if (type.GetConstructors().Count(c => c.IsDefined(typeof(ZXInjectionConstructor), true)) > 0)
{
ctor = type.GetConstructors().Where(c => c.IsDefined(typeof(ZXInjectionConstructor), true)).OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();
}
else
{
ctor = type.GetConstructors().OrderByDescending(c => c.GetParameters().Length).First();
}

List<object> parameterlist = new List<object>();
foreach (ParameterInfo parameter in ctor.GetParameters())
{
string parameterType = parameter.ParameterType.FullName;
Type targetType = ZXContainerDicationary[parameterType];
object oParameter = this.ObjectInstance(targetType); //隐形的跳出条件:找到最后后一个依赖的五参数构造函数后就不再去递归了;
parameterlist.Add(oParameter);
}

object oInstance = Activator.CreateInstance(type, parameterlist.ToArray());//调用的五参数构造函数;//如果有两级依赖
return oInstance;

}
}
}

IZXContainer container = new ZXContainer();//创建一个容器
container.RegisterType<IPhone, ApplePhone>();//告诉容器---抽象和细节的关系
container.RegisterType<IHeadphone, Headphone>();
container.RegisterType<IMicrophone, Microphone>();
container.RegisterType<IPower, Power>();
container.RegisterType<IBaseBll, BaseBll>();
IPhone phone = container.Resolve<IPhone>();//获取对象的实例

 

反射:

public class ObjectFactory
{
public static IPhone CreatePhone()
{
string classModule = ConfigurationManager.AppSettings["iPhoneType"];
Assembly assemly = Assembly.Load(classModule.Split(',')[1]);
Type type = assemly.GetType(classModule.Split(',')[0]);
return (IPhone)Activator.CreateInstance(type);//无参数构造函数
}

public static IPhone CreatePhone(IBaseBll iBLL)
{
string classModule = ConfigurationManager.AppSettings["iPhoneType"];
Assembly assemly = Assembly.Load(classModule.Split(',')[1]);
Type type = assemly.GetType(classModule.Split(',')[0]);
return (IPhone)Activator.CreateInstance(type, new object[] { iBLL });
}
}

 

标签:自定义,DI,IOC,typeof,type,ZXInjectionConstructor,ctor,构造函数
From: https://www.cnblogs.com/csj007523/p/16729224.html

相关文章

  • (一)Radis基础知识
       1、什么是Redis?Redis是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。Redis与其他key-value缓存产品有以下三个特点:Redis支持......
  • 【Redis】Key过期了为什么内存没有释放
    SET除了可以设置key-value之外,还可以设置key的过期时间。  如果想要修改key的值,使用set命令,而没有加上过期时间的参数,那么这个key的过期时间将会被擦除。......
  • Redis持久化
    为了防止Redis宕机导致数据全部清空,所以有持久化操作 显然不能高频的生成RDB文件进行备份,毕竟数据多,而且操作耗时。所以需要将增删改的操作写进AOF文件 但是也不能......
  • 如何解决 QMediaPlayer 占用歌曲导致 PermissionError: [Error 13] 的问题
    问题描述当我们使用QMediaPlayer播放歌曲时,歌曲文件的句柄会被占用。如果想用使用mutagen库对正在播放地歌曲进行数据写入,就会出现下述问题:Traceback(mostrecentc......
  • 吉特日化MES & Redis 运行远程访问的配置
     在吉特日化MES系统部署实施过程中,经常需要配置Redis需要运行远程IP访问Redis。使用Redis的目的主要是为了解决缓存的问题,同时解决打印过程中推送数据的问题。......
  • Visual Studio 2022 开发 STM32 单片机 - 环境搭建点亮LED灯
    安装VS2022社区版软件选择基础的功能就好  安装VisualGDB软件(CSDN资源) 按照提示一步一步安装就好 VisualGDB激活软件(CSDN资源)将如下软件放在VisualGDB的安......
  • Value error: 'ascii' codec can't decode byte 0xe6 in position 26: ordinal not in
    原因:工作空间中有中文编码问题,导致的运行ros异常解决办法:1、解决urdf生成异常问题urdf文件中不允许有中文,所有当输入中文的时候容易出问题,解决方案:①在根目录下:/opt/ro......
  • 自定义注解
    格式元注解public@interface注解名称{属性列表}本质注解本质上就算一个接口该接口默认继承Annotation接口属性接口中的抽象方法要求属性的返回......
  • Redis面试题
    1.项目中是否使用过redis?为什么要使用redis?使用过之前使用的都是修改某个value值,如登录账号被锁定30分钟,查看还剩余的时间,或者想将账号由锁定状态更新为未锁定状态,删......
  • nginx禁止直接通过ip进行访问并跳转到自定义403页面
    配置server{listen80default;server_name_;error_page403/403.html;location=/403.html{roothtml;}location/{......