How to build a lightweight DI (dependency injection) and di Injection

Source: Internet
Author: User

How to build a lightweight DI (dependency injection) and di Injection

Concept: dependency injection is similar to the factory mode in IOC mode. It is a mode that solves the dependency coupling between callers and callers. It solves the dependency between objects, so that the object only depends on the IOC/DI container and does not directly depend on each other. This achieves loose coupling. Then, when the object is created, the IOC/DI container injects the dependent object into its body, therefore, it is also called the dependency injection mode to maximize loose coupling;

So what is dependency? The following code:

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 }

The following code indicates that A depends on B, because A's method behavior is dependent on m Implementation of B.

Container information:

1 /// <summary> 2 // configuration item in dependency injection (injection container) 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 // when the container creates an object, whether to return 11 // </summary> 12 public Boolean Singleton {13 get {return _ singleton;} 14 set {_ singleton = value;} in Singleton Mode ;} 15} 16 17 /// <summary> 18 // map19 of the object dependency injection relationship /// </s Ummary> 20 public Dictionary <String, String> Map {21 get {return _ maps;} 22 set {_ maps = value ;} 23} 24 25 /// <summary> 26 // typeFullName27 of the object /// </summary> 28 public String Type {get; set ;} 29 30 /// <summary> 31 32 // Add the injection link 33 34 /// </summary> 35 36 /// <param name = "propertyName"> attribute name </param> 37 38 // <param name = "item"> inject container </param> 39 internal void AddMap (String propertyName, mapItem) {40 AddMap (propertyName, item. name ); 41} 42 43 // <summary> 44 45 // inject 46 47 // </summary> 48 49 // <param name = "propertyName"> attribute name </param> 50 51 // <param name = "injectBy"> Object name </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 // target object 62 63 // </summary> 64 [NotSave] 65 int Ernal Object TargetObject {66 get {return _ obj;} 67 set {_ obj = value;} 68} 69 70 private Type _ type; 71 72 // <summary> 73 74 // target Type 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}

To use this container, we generally need to call the following external methods:

/// <Summary> /// create an Ioc-processed object. The result is not a singleton. /// Check whether injection is required. /// </Summary> /// <typeparam name = "T"> </typeparam> /// <returns> </returns> public static T Create <T> () {return (T) CreateObject (typeof (T), null) ;}/// <summary> // create an Ioc-processed object. The result is not a singleton. /// Check whether injection is required. /// </Summary> /// <param name = "targetType"> </param> /// <param name = "invokerName"> if it is automatically assembled Based on the interface, </param> // <returns> </returns> private static Object CreateObject (Type targetType, Object invoker) {if (targetType = null) return null; if (targetType. isInterface) {// interface return CreateByInterface (targetType, invoker);} // here we use AOP to construct an Object. For details, refer to the previous blog Object objTarget = AopContext. createObjectBySub (targe TType); // Inject (objTarget) into IOC; return objTarget;} // <summary> // configure IOC according to the container ), inject the dependency into the created Object // </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;} createInstanceAndInjec T (mapItem, obj );} /// <summary> /// search for DI container by type /// </summary> /// <param name = "t"> </param> // <returns> </returns> private static MapItem getMapItemByType (Type t) {Dictionary <String, MapItem> resolvedMap = Instance. resolvedMap; // container foreach (KeyValuePair <String, MapItem> entry in resolvedMap) {MapItem item = entry. value; if (t. fullName. equals (item. type) return item;} return null ;}/// <Summary> // IOC injection: checks the attributes of an object and injects the object according to the configuration. If no configuration exists, then it is automatically assembled /// </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 (ta RgetType); // create an object based on reflection} // check all properties PropertyInfo [] properties = targetType. getProperties (BindingFlags. public | BindingFlags. instance); foreach (PropertyInfo p in properties) {if (! P. CanRead) continue; if (! P. CanWrite) continue; // skip if (! P. PropertyType. IsInterface) continue; // perform the injection check on the Interface // future // if there is an injection configuration Object mapValue = getMapValue (mapItem. Map, p); if (mapValue! = Null) {p. setValue (objTarget, mapValue, null);} // if no else {Object propertyValue = p. getValue (objTarget, null); // automatically assemble 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 ;}

Automatic Assembly if container check does not exist

// IOC injection: Check the Object attributes. Inject the Object according to the configuration. If no configuration is configured, the private static Object createInstanceAndInject (MapItem mapItem) {return createInstanceAndInject (mapItem, null) is automatically assembled );} /// <summary> /// check whether attribute information exists in the ing relationship. // </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> // obtain the object based on the name in the configuration file of dependency injection. Singleton determines whether to use a Singleton instance based on the configuration attribute. /// </Summary> /// <param name = "objectName"> </param> /// <returns> </returns> public static Object GetByName (String objectName) {if (Instance. resolvedMap. containsKey (objectName) = false) return null; MapItem item = Instance. resolvedMap [objectName]; if (item = null) return null; if (item. singleton) return Instance. objectsByName [objectName]; else return createInstanceAndInject (item );}

Automatically bind objects based on interfaces

// Obtain the automatically bound private static Object getAutoWiredValue (Type interfaceType) {List <Type> typeList = GetTypeListByInterface (interfaceType); if (typeList. count = 0) {return null; // return null} else if (typeList. count = 1) {return Create (typeList [0], interfaceType);} else {StringBuilder msg = new StringBuilder (); foreach (Type t in typeList) {msg. append (t. fullName + ",");} throw new Exception (s Tring. Format ("there are multiple interface implementations. The interface = {0}, implementation = {1} is not explicitly specified and cannot be automatically injected. ", InterfaceType. fullName, msg) ;}}// obtain the instance public static List <Type> GetTypeListByInterface (Type interfaceType) {List <Type> typeList = new List <Type> () based on the interface (); foreach (KeyValuePair <String, Type> kv in Instance. typeList) {if (rft. isInterface (kv. value, interfaceType) {typeList. add (kv. value) ;}} return typeList ;}

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.