IOC--自定义IOC容器
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
{
}