IOC--自定义IOC容器

17 篇文章 0 订阅

IOC容器

  • 基于IoC思想,管理对象创建的核心对象
  • 常见IoC容器
    • Autofac、Unity、DryIoc、Spring.Net、Injection、SimpleIOC、SmartIOC、………

IoC模式的使用

自定义容器过程

基本类型管理:瞬时实例、单例

瞬时实例:每次创建的时候都是新的实例,new ()

单例实例:只有第一次创建,之后都是用的第一个实例,不会重新new 和覆盖。

无限级依赖注入

在构造函数中,注入的实例中实例有自己的注入实例,需要使用递归进行无限注入

属性注入

在使用的类中,进行属性就可以完成属性注入

注意:属性注入需要在构造函数执行完之后。

单接口多实现注入

同一个接口有多个继承,但是不同的界面需要不同的继承的注入,所以需要实现单接口多实现注入

核心代码如下:

初始化:
public static XiaohaiIoc Default
{
    get
    {
        if (_default == null)
        {
            lock (_instanceLock)
            {
                if (_default == null)
                {
                    _default = new XiaohaiIoc();
                }
            }
        }
        return _default;
    }
}
单个类型的注册
瞬时状态
public void Register<T>()
{
    //_objectDic.Add(typeof(T).FullName!, typeof(T));
    _instenceDic.Add(typeof(T).FullName!,
        new InstenceModel
        {
            ObjectType = typeof(T),
            IsSinglton = false,
        });
}
单例模式
public void RegisterSingle<T>()
{
    _instenceDic.Add(typeof(T).FullName!,
        new InstenceModel
        {
            ObjectType = typeof(T),
            IsSinglton = true,
        });
}
带接口的注册(多继承关系类注册)
瞬时状态
public void Register<TFrom, TTo>(String token = "") where TTo : TFrom
{
    GetRegister<TFrom, TTo>(false, token);
}
 private void GetRegister<TFrom, TTo>(bool bl, String token = "")
 {
     string key = typeof(TFrom).FullName + "_%XH%_" + (string.IsNullOrEmpty(token) ? typeof(TTo).Name : token);
     _instenceDic.Add(key, new InstenceModel
     {
         ObjectType = typeof(TTo),
         IsSinglton = bl,
     });
 }
单例模式:
public void RegisterSingle<TFrom, TTo>(String token = "") where TTo : TFrom
{
    GetRegister<TFrom, TTo>(true, token);
}
 private void GetRegister<TFrom, TTo>(bool bl, String token = "")
 {
     string key = typeof(TFrom).FullName + "_%XH%_" + (string.IsNullOrEmpty(token) ? typeof(TTo).Name : token);
     _instenceDic.Add(key, new InstenceModel
     {
         ObjectType = typeof(TTo),
         IsSinglton = bl,
     });
 }
获取实例
 public T Resolve<T>()
 {
     string key = typeof(T).FullName!;
     if (_instenceDic.ContainsKey(key))
     {
         // 单例模式没有对象 和瞬时模式都需要创建对象
         if ((_instenceDic[key].IsSinglton && _instenceDic[key].Instence is null) || !_instenceDic[key].IsSinglton)
             return (T)CreateInstence(key, _instenceDic[key].ObjectType);
         //单例模式 有对象直接返回
         return (T)_instenceDic[key].Instence;
     }
     else
         return default(T)!;
 }

private object CreateInstence(string key, Type type)
{
    #region 检查构造函数

    // 获取所有的构造函数
    ConstructorInfo[] cis = _instenceDic[key].ObjectType.GetConstructors();
    // 获取所有的参数
    ParameterInfo[] cpis = cis[0].GetParameters();
    // 创建args 参数列表
    List<object> objects = new List<object>();
    foreach (ParameterInfo cpi in cpis)
    {
        string paramTypeKey = cpi.ParameterType.FullName!;
        if (cpi.IsDefined(typeof(DependyAttribute), false))
        {
            var attr = cpi.GetCustomAttribute<DependyAttribute>();
            paramTypeKey += "_%XH%_" + attr.Token;
        }

        if (_instenceDic.ContainsKey(paramTypeKey!))
        {
            if (_instenceDic[paramTypeKey].IsSinglton)
            {
                if (_instenceDic[paramTypeKey].Instence is null)
                    //_instenceDic[paramTypeKey].Instence = Activator.CreateInstance(_instenceDic[paramTypeKey].ObjectType)!;
                    _instenceDic[paramTypeKey].Instence = CreateInstence(paramTypeKey, _instenceDic[paramTypeKey].ObjectType);
            }
            else
                _instenceDic[paramTypeKey].Instence = CreateInstence(paramTypeKey, _instenceDic[paramTypeKey].ObjectType);

            objects.Add(_instenceDic[paramTypeKey].Instence);
        }
        else
            objects.Add(null!);
    }

    #endregion

    // 实例化对象
    var obj = Activator.CreateInstance(_instenceDic[key].ObjectType, objects.ToArray());
    _instenceDic[key].Instence = obj!;

    #region 检查属性的注入

    // 那些属性需要注入 可以通过特性进行区分
    PropertyInfo[] pis = type.GetProperties();
    foreach (var pi in pis)
    {
        // 判断属性是否有特定标记 如果有实例化这个属性
        if (pi.IsDefined(typeof(DependyAttribute), false))
        {
            var attr = pi.GetCustomAttribute<DependyAttribute>();

            // 获得属性注入 
            string paramTypeKey = pi.PropertyType.FullName! + "_%XH%_" + attr.Token;
            if (_instenceDic.ContainsKey(paramTypeKey!))
            {
                if (_instenceDic[paramTypeKey].IsSinglton)
                {
                    if (_instenceDic[paramTypeKey].Instence is null)
                        _instenceDic[paramTypeKey].Instence = CreateInstence(paramTypeKey, _instenceDic[paramTypeKey].ObjectType);
                }
                else
                    _instenceDic[paramTypeKey].Instence = CreateInstence(paramTypeKey, _instenceDic[paramTypeKey].ObjectType);

                // 如果有实例,已经创建过,设置给当前对象的对应属性
                // 参数:设置给哪个对象实例的属性
                pi.SetValue(obj, _instenceDic[paramTypeKey].Instence);
            }
        }
    }

    #endregion

    return _instenceDic[key].Instence;
}
注入模式类:
 class InstenceModel
 {
     public bool IsSinglton { get; set; } // 是不是单例模式
     public Type ObjectType { get; set; } // 数据类型
     public object Instence { get; set; } // 初始化数据
 }
特性类:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter)]
public class DependyAttribute:Attribute
{
    public DependyAttribute()
    {
        
    }
    public string Token { get; set; }
    public DependyAttribute(string token = "")
    {
        Token = token;
    }
}
在其他类中使用情况:
属性注入:

需要在对象构造函数走完才能注入成功

 [Dependy]
 public ILoginBLL loginBLL { get; set; }
单接口多实现注入:

同过特性类,加入token ,来判断是哪个类

public MainViewModel([Dependy("SqlServerDA")]IDataAccess dataAccess) // SqlServerDA
{
}
public LoginBLL([Dependy("MySqlDA")]IDataAccess dataAccess) // MySql
{
}
  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值