using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using Zhaizj.Framework.Reflection; using Zhaizj.Framework.Web.Mvc; using Zhaizj.Framework.Web.Mvc.Interface; namespace Zhaizj.Framework.DI { /// /// IOC 管理容器 /// public class ObjectContext { private static readonly ILog logger = LogManager.GetLogger( typeof( ObjectContext ) ); private static Object syncRoot = new object(); private static volatile ObjectContext _instance; private ObjectContext() { } /// /// 容器的实例(单例) /// public static ObjectContext Instance { get { if (_instance == null) { lock (syncRoot) { if (_instance == null) { ObjectContext ctx = new ObjectContext(); InitInject( ctx ); _instance = ctx; } } } return _instance; } } private static void InitInject( ObjectContext ctx ) { loadAssemblyAndTypes( ctx ); resolveAndInject( ctx ); addNamedObjects( ctx ); } private Dictionary _assemblyList = new Dictionary(); private Dictionary _assemblyTypes = new Dictionary(); private Dictionary _typeList = new Dictionary(); private Dictionary _resolvedMap = new Dictionary(); private Hashtable _objectsContainerByName = new Hashtable(); private Hashtable _objectsContainerByType = new Hashtable(); private Dictionary _dtoList = new Dictionary(); /// /// 所有纳入容器管理的程序集 /// public Dictionary AssemblyList { get { return _assemblyList; } set { _assemblyList = value; } } /// /// 所有程序集的 Dictionary /// public Dictionary AssemblyTypes { get { return _assemblyTypes; } set { _assemblyTypes = value; } } /// /// 已经解析过的类型 /// public Dictionary ResolvedMap { get { return _resolvedMap; } set { _resolvedMap = value; } } /// /// 所有纳入容器管理的类型 /// public Dictionary TypeList { get { return _typeList; } set { _typeList = value; } } /// /// 根据名称罗列的对象表 /// public Hashtable ObjectsByName { get { return _objectsContainerByName; } set { _objectsContainerByName = value; } } /// /// 根据类型罗列的对象表 /// public Hashtable ObjectsByType { get { return _objectsContainerByType; } set { _objectsContainerByType = value; } } /// /// 获取所有的dto(工厂),用于创建dto对象 /// public Dictionary DtoList { get { return _dtoList; } set { _dtoList = value; } } //---------------------------------------------------------------------------------------------------- /// /// 根据依赖注入的配置文件中的 name 获取对象 /// /// /// 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 ); } /// /// 从缓存中取对象(有注入的就注入,没有注入的直接生成),结果是单例 /// /// /// public static Object GetByType( String typeFullName ) { if (Instance.TypeList.ContainsKey( typeFullName ) == false) return null; Type t = Instance.TypeList[typeFullName]; return GetByType( t ); } /// /// 从缓存中取对象(有注入的就注入,没有注入的直接生成),结果是单例 /// /// /// public static Object GetByType( Type t ) { if (t == null) return null; Object result = Instance.ObjectsByType[t.FullName]; if (result == null) { MapItem mapItem = getMapItemByType( t ); if (mapItem != null) { result = createInstanceAndInject( mapItem ); } else { result = rft.GetInstance( t ); } Instance.ObjectsByType[t.FullName] = result; } return result; } /// /// 根据type,不从缓存(pool)中取,而是全新创建实例(有注入的就注入,没有注入的直接生成),肯定不是单例 /// /// /// public static Object CreateObject( Type t ) { if (t == null) return null; MapItem mapItem = getMapItemByType( t ); if (mapItem == null) return rft.GetInstance( t ); else return createInstanceAndInject( mapItem ); } /// /// 根据type,不从缓存(pool)中取,而是全新创建实例(有注入的就注入,没有注入的直接生成),肯定不是单例 /// /// /// public static Object CreateObject( String typeFullName ) { if (Instance.TypeList.ContainsKey( typeFullName ) == false) return null; Type t = Instance.TypeList[typeFullName]; return CreateObject( t ); } /// /// 根据type,不从缓存(pool)中取,而是全新创建实例(有注入的就注入,没有注入的直接生成),肯定不是单例 /// /// /// public static T Create() { return (T)CreateObject( typeof( T ) ); } private static MapItem getMapItemByType( Type t ) { Dictionary resolvedMap = Instance.ResolvedMap; foreach (KeyValuePair entry in resolvedMap) { MapItem item = entry.Value; if (t.FullName.Equals( item.Type )) return item; } return null; } private static Object createInstanceAndInject( MapItem item ) { Object currentObject = rft.GetInstance( item.TargetObject.GetType() ); Dictionary maps = item.Map; if (maps.Count > 0) { foreach (KeyValuePair entry in maps) { Object propertyValue = GetByName( entry.Value.ToString() ); if (propertyValue != null) { ReflectionUtil.SetPropertyValue( currentObject, entry.Key, propertyValue ); } } } return currentObject; } //---------------------------------------------------------------------------------------------- private static void loadAssemblyAndTypes( ObjectContext ctx ) { String appSettings = cfgHelper.GetAppSettings( "InjectAssembly" ); if (strUtil.IsNullOrEmpty( appSettings )) return; String[] strArray = appSettings.Split( new char[] { ',' } ); foreach (String asmStr in strArray) { if (strUtil.IsNullOrEmpty( asmStr )) continue; String asmName = asmStr.Trim(); Assembly assembly = loadAssemblyPrivate( asmName, ctx ); findTypesPrivate( assembly, asmName, ctx ); } } private static Assembly loadAssemblyPrivate( String asmName, ObjectContext ctx ) { Assembly assembly = Assembly.Load( asmName ); ctx.AssemblyList.Add( asmName, assembly ); return assembly; } private static void findTypesPrivate( Assembly assembly, String asmName, ObjectContext ctx ) { Type[] types = assembly.GetTypes(); ctx.AssemblyTypes.Add( asmName, types ); foreach (Type type in types) { ctx.TypeList.Add( type.FullName, type ); if (rft.IsInterface( type, typeof( IDto ) )) { ctx.DtoList.Add( strUtil.TrimEnd( type.FullName, "Dto" ), (IDto)rft.GetInstance( type ) ); } } } /// /// 加载程序集并返回此程序集,如果容器中已存在,则直接从容器中获取 /// /// /// public static Assembly LoadAssembly( String asmName ) { Assembly assembly;// = Instance.AssemblyList[asmName]; Instance.AssemblyList.TryGetValue( asmName, out assembly ); if (assembly == null) { assembly = Assembly.Load( asmName ); Instance.AssemblyList.Add( asmName, assembly ); } return assembly; } /// /// 加载某程序集里的所有类型,如果容器中已存在,则直接从容器中获取 /// /// /// public static Type[] FindTypes( String asmName ) { Type[] types;// = Instance.AssemblyTypes[asmName]; Instance.AssemblyTypes.TryGetValue( asmName, out types ); if (types == null) { types = LoadAssembly( asmName ).GetTypes(); Instance.AssemblyTypes.Add( asmName, types ); foreach (Type type in types) { Instance.TypeList.Add( type.FullName, type ); } } return types; } //---------------------------------------------------------------------------------------------- private static void resolveAndInject( ObjectContext ctx ) { List maps = cdb.findAll(); if (maps.Count <= 0) return; Dictionary resolvedMap = new Dictionary(); logger.Info( "resolve item begin..." ); resolveMapItem( maps, resolvedMap, ctx ); logger.Info( "inject Object begin..." ); injectObjects( maps, resolvedMap ); ctx.ResolvedMap = resolvedMap; } private static void resolveMapItem( List maps, Dictionary resolvedMap, ObjectContext ctx ) { foreach (MapItem oneMap in maps) { Type type;// = ctx.TypeList[oneMap.Type]; ctx.TypeList.TryGetValue( oneMap.Type, out type ); if (type == null) continue; logger.Info( "resolve:" + oneMap.Name ); if (oneMap.Singleton) { // ObjectsByType中存储的都是单例对象 oneMap.TargetObject = checkByCache( type, ctx ); } else { oneMap.TargetObject = rft.GetInstance( type ); } resolvedMap[oneMap.Name] = oneMap; } } private static Object checkByCache( Type t, ObjectContext ctx ) { if (ctx.ObjectsByType[t.FullName] == null) { ctx.ObjectsByType.Add( t.FullName, rft.GetInstance( t ) ); } return ctx.ObjectsByType[t.FullName]; } private static void injectObjects( List mapItems, Dictionary resolvedMap ) { foreach (MapItem item in mapItems) { logger.Info( "inject:" + item.Name ); Dictionary maps = item.Map; if (maps.Count <= 0) continue; foreach (KeyValuePair entry in maps) { logger.Info( "------inject key:" + entry.Key.ToString() ); MapItem referencedItem;// = resolvedMap[entry.Value.ToString()]; resolvedMap.TryGetValue( entry.Value.ToString(), out referencedItem ); if (referencedItem != null) { ReflectionUtil.SetPropertyValue( item.TargetObject, entry.Key, referencedItem.TargetObject ); } } } } //-------------------------------------------------------------------------------- private static void addNamedObjects( ObjectContext ctx ) { Dictionary resolvedMap = ctx.ResolvedMap; Hashtable namedObjects = new Hashtable(); foreach (KeyValuePair entry in resolvedMap) { MapItem item = entry.Value; namedObjects.Add( item.Name, item.TargetObject ); } ctx.ObjectsByName = namedObjects; } /// /// 根据容器配置,将依赖关系注入到已创建的对象中 /// /// public static void Inject( Object obj ) { if (obj == null) return; Type t = obj.GetType(); Dictionary resolvedMap = ObjectContext.Instance.ResolvedMap; foreach (KeyValuePair pair in resolvedMap) { MapItem item = pair.Value; if (item.Type.Equals( t.FullName ) == false) continue; Dictionary maps = item.Map; if (maps.Count <= 0) return; injectObjectSingle( obj, resolvedMap, maps ); return; } } private static void injectObjectSingle( Object obj, Dictionary resolvedMap, Dictionary maps ) { foreach (KeyValuePair entry in maps) { logger.Info( "------inject key:" + entry.Key.ToString() ); MapItem referencedItem; resolvedMap.TryGetValue( entry.Value.ToString(), out referencedItem ); if (referencedItem != null) { ReflectionUtil.SetPropertyValue( obj, entry.Key, referencedItem.TargetObject ); } } } } }