首页 > 学院 > 开发设计 > 正文

如何构建一个轻量级级的DI(依赖注入)

2019-11-17 02:19:01
字体:
来源:转载
供稿:网友

如何构建一个轻量级级的DI(依赖注入)

概念:依赖注入与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
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表