概念:依赖注入与IOC模式类似工厂模式,是一种解决调用者和被调用者依赖耦合关系的模式;它解决了对象之间的依赖关系,使得对象只依赖IOC/DI容器,不再直接相互依赖,实现松耦合,然后在对象创建时,由IOC/DI容器将其依赖的对象注入其体内,故又称依赖注入依赖注射模式,最大程度实现松耦合;
那么什么是依赖?如下代码:
1 public class A{2 PRivate B b;3 public A(B b){4 this.b = b;5 }6 public void mymethod(){7 b.m();8 }9 }
如下代码表示A依赖B,因为A的方法行为mymehtod有一部分要依赖B的方法m实现。
容器信息:
1 /// <summary> 2 /// 依赖注入中的配置项(注入容器) 3 /// </summary> 4 public class MapItem : { 5 6 private Boolean _singleton = true; 7 private Dictionary<String, String> _maps = new Dictionary<String, String>(); 8 9 /// <summary>10 /// 容器创建对象的时候,是否以单例模式返回11 /// </summary>12 public Boolean Singleton {13 get { return _singleton; }14 set { _singleton = value; }15 }16 17 /// <summary>18 /// 对象依赖注入关系的 map19 /// </summary>20 public Dictionary<String, String> Map {21 get { return _maps; }22 set { _maps = value; }23 }24 25 /// <summary>26 /// 对象的 typeFullName27 /// </summary>28 public String Type { get; set; }29 30 /// <summary>31 32 /// 添加注入关系33 34 /// </summary>35 36 /// <param name="propertyName">属性名称</param>37 38 /// <param name="item">注入容器</param>39 internal void AddMap( String propertyName, MapItem item ) {40 AddMap( propertyName, item.Name );41 }42 43 /// <summary>44 45 /// 注入46 47 /// </summary>48 49 /// <param name="propertyName">属性名称</param>50 51 /// <param name="injectBy">对象名称</param>52 internal void AddMap( String propertyName, String injectBy ) {53 this.Map.Add( propertyName, injectBy );54 }55 56 57 private Object _obj;58 59 /// <summary>60 61 /// 目标对象62 63 /// </summary>64 [NotSave]65 internal Object TargetObject {66 get { return _obj; }67 set { _obj = value; }68 }69 70 private Type _type;71 72 /// <summary>73 74 /// 目标类型75 76 /// </summary>77 [NotSave]78 internal Type TargetType {79 get {80 81 if (_type != null) return _type;82 if (TargetObject != null) return TargetObject.GetType();83 return null;84 }85 set { _type = value; }86 }87 88 }
那么看如何使用这个容器,我们一般外部需要调用的方法为:
/// <summary> /// 创建一个经过Ioc处理的对象,结果不是单例。 /// 检测是否需要注入。 /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static T Create<T>() { return (T)CreateObject(typeof(T), null); } /// <summary> /// 创建一个经过Ioc处理的对象,结果不是单例。 /// 检测是否需要注入。 /// </summary> /// <param name="targetType"></param> /// <param name="invokerName">如果是根据接口自动装配,</param> /// <returns></returns> private static Object CreateObject(Type targetType, Object invoker) { if (targetType == null) return null; if (targetType.IsInterface) { ///接口 return CreateByInterface(targetType, invoker); } //这里是用AOP实现对象的构建,可以参看上一篇博客 Object objTarget = AopContext.CreateObjectBySub(targetType); //进行IOC注入 Inject(objTarget); return objTarget; }/// <summary> /// 根据容器配置(IOC),将依赖关系注入到已创建的对象中 /// </summary> /// <param name="obj"></param> public static void Inject(Object obj) { if (obj == null) return; Type t = obj.GetType(); MapItem mapItem = getMapItemByType(t); if (mapItem == null) { mapItem = new MapItem(); mapItem.TargetType = t; mapItem.TargetObject = obj; } createInstanceAndInject(mapItem, obj); } /// <summary> /// 根据类型查找DI容器 /// </summary> /// <param name="t"></param> /// <returns></returns> private static MapItem getMapItemByType(Type t) { Dictionary<String, MapItem> resolvedMap = Instance.ResolvedMap;//当前对象的键值对容器 foreach (KeyValuePair<String, MapItem> entry in resolvedMap) { MapItem item = entry.Value; if (t.FullName.Equals(item.Type)) return item; } return null; } /// <summary> /// IOC注入:检查对象的属性,根据配置注入,如果没有配置,则自动装配 /// </summary> /// <param name="mapItem"></param> /// <returns></returns> private static Object createInstanceAndInject(MapItem mapItem, Object objTarget) { Type targetType = mapItem.TargetType; if (targetType.IsAbstract) { logger.Info("type is abstract=>" + targetType.FullName); return null; } if (objTarget == null) { objTarget = rft.GetInstance(targetType);//根据反射创建对象 } // 检查所有属性 PropertyInfo[] properties = targetType.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (PropertyInfo p in properties) { if (!p.CanRead) continue; if (!p.CanWrite) continue; // 不是接口的跳过 if (!p.PropertyType.IsInterface) continue; // 对接口进行注入检查 //------------------------------------------------- // 如果有注入配置 Object mapValue = getMapValue(mapItem.Map, p); if (mapValue != null) { p.SetValue(objTarget, mapValue, null); } // 如果没有注入 else { Object propertyValue = p.GetValue(objTarget, null); // 自动装配 if (propertyValue == null) { logger.Info("property=>" + targetType.Name + "." + p.Name); propertyValue = getAutoWiredValue(p.PropertyType); if (propertyValue != null) { p.SetValue(objTarget, propertyValue, null); } else { logger.Info("property is null=>" + p.Name); } } } } return objTarget; }
容器检查如果没有则自动装配
// IOC注入:检查对象的属性,根据配置注入,如果没有配置,则自动装配 private static Object createInstanceAndInject(MapItem mapItem) { return createInstanceAndInject(mapItem, null); } /// <summary> /// 检查映射关系中是否存在属性信息 /// </summary> /// <param name="maps"></param> /// <param name="p"></param> /// <returns></returns> private static Object getMapValue(Dictionary<String, String> maps, PropertyInfo p) { if (maps == null || maps.Count == 0) return null; foreach (KeyValuePair<String, String> entry in maps) { Object x = GetByName(entry.Value); if (x != null) return x; } return null; } /// <summary> /// 根据依赖注入的配置文件中的 name 获取对象。根据配置属性Singleton决定是否单例。 /// </summary> /// <param name="objectName"></param> /// <returns></returns> public static Object GetByName(String objectName) { if (Instance.ResolvedMa
新闻热点
疑难解答