private object AppendProperties(object result, BindElement bind, int depth) { //如果是单例,则不在进行各个属性的再次查找,赋值 if (bind.Issingleton) { return(result); } //对于注册类型可用于当前对象属性装配的逻辑查找 CreateAssigment(bind); if (bind.Assigment.Action != null) { //根据匹配的可装配的节点生成实例对象 IList <object> values = new List <object>(); foreach (var item in bind.Assigment.RegisterTypes) { values.Add(CreateInstance(item.Name, item.BindType, depth + 1)); //注意:这里有递归的调用(为防止死循环的发生,需要对调用深度进行限制) } //对所有可装配的属性进行赋值 bind.Assigment.Action(result, values.ToArray()); } return(result); }
public void Register(string name, Type baseType, Type implementType, bool singleton, bool instance) { if (baseType == null) { throw new ArgumentNullException("baseType"); } if (implementType == null) { throw new ArgumentNullException("implementType"); } //如果指定了节点的名称,则判重 if (!string.IsNullOrEmpty(name)) { name = name.Trim(); int count = BIND_DICTIONARY.Values.Count(c => string.Equals(name, c.Name, StringComparison.OrdinalIgnoreCase)); if (count > 0) { throw new Exception(string.Format("名称为[{0}]的节点已存在", name)); } } //根据指定的name和当前注册的基类型,计算缓存的key string key = GetCacheName(name, baseType); //验证注册类型是否具有继承关系 if (baseType != implementType && !baseType.IsAssignableFrom(implementType)) { throw new ArgumentOutOfRangeException(string.Format("类型[{0}]和类型[{1}]不具有继承关系", baseType.FullName, implementType.FullName)); } if (BIND_DICTIONARY.ContainsKey(key)) { throw new ArgumentException(string.Format("类型[{0}]已经存在名称为[{1}]的项", baseType.FullName, name)); } lock (BIND_DICTIONARY) { if (BIND_DICTIONARY.ContainsKey(key)) { throw new ArgumentException(string.Format("类型[{0}]已经存在名称为[{1}]的项", baseType.FullName, name)); } BindElement reg = new BindElement(); reg.Name = name; reg.BindType = baseType; reg.IsInstance = instance; reg.Issingleton = singleton; reg.ToType = implementType; BIND_DICTIONARY.Add(key, reg); } }
private BindElement GetBindElement(Type type, string name) { BindElement bind = null; var values = BIND_DICTIONARY.Values; if (string.IsNullOrEmpty(name)) { //首先进行属性类型的精确匹配 bind = values.FirstOrDefault(c => c.BindType == type && string.IsNullOrEmpty(c.Name)); if (bind != null) { return(bind); } //查找能够与当前属性类型匹配的其子类的信息 foreach (var item in values) { //TOTO:这里是否限制在未指定名称的范围内查找 if (string.IsNullOrEmpty(item.Name) && type.IsAssignableFrom(item.BindType)) { return(item); } } return(null); } //如果指定了名称,则判断使用该名称的注册类型是否能够生成当前的属性值 bind = values.FirstOrDefault(c => string.Equals(name, c.Name, StringComparison.OrdinalIgnoreCase)); if (bind == null) { throw new Exception(string.Format("未找到名称为[{0}]的注册节点", name)); } if (!type.IsAssignableFrom(bind.BindType)) { throw new Exception(string.Format("节点[{0}]注册的类型[{0}]和当前的属性类型[{1}]不具有继承关系", name, bind.BindType.FullName, type.FullName)); } return(bind); }
private void CreateAssigment(BindElement bind) { if (bind.Assigment != null) { return; } lock (bind) { if (bind.Assigment != null) { return; } IList <BindElement> list_be = new List <BindElement>(); IList <PropertyInfo> list_pi = new List <PropertyInfo>(); Type elType = bind.AgentType == null ? bind.ToType : bind.AgentType; var pis = elType.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var pi in pis) { //如果此属性不可写,则直接忽略 if (!pi.CanWrite) { continue; } //查找属性是否有装配标记(没有则直接忽略) var atts = pi.GetCustomAttributes(typeof(AssembleAttribute), false); if (atts == null || atts.Length != 1) { continue; } var assemble = atts[0] as AssembleAttribute; if (assemble == null) { continue; } string name = assemble.Name; if (!string.IsNullOrEmpty(name)) { name = name.Trim(); } //开始匹配能够适配当前属性的注册节点 var be = GetBindElement(pi.PropertyType, name); //如果没找到匹配的注册类型,则抛出异常 if (be == null) { throw new Exception(string.Format("未能在注册类型中匹配类型[{0}]中的属性[{1}]", bind.BindType.FullName, pi.Name)); } //记录匹配的结果 list_pi.Add(pi); list_be.Add(be); } PropertiesAction assigment = new PropertiesAction(); if (list_pi.Count > 0) { //记录匹配的节点 assigment.RegisterTypes = list_be; //利用得到匹配的属性集合,得到赋值对应属性的委托 assigment.Action = EmitHelper.CreatePropertiesAction(list_pi.ToArray()); } bind.Assigment = assigment; } }
private object CreateInstance(string name, Type type, int depth) { //验证装配深度 if (depth > m_MaxDepth) { throw new Exception(string.Format("当前的装配深度:{0},已超过设定值:{1}", depth, m_MaxDepth)); } BindElement bind = null; string key = GetCacheName(name, type); if (!BIND_DICTIONARY.TryGetValue(key, out bind)) { //未找到注册节点的所有接口类型,抛出异常 if (type.IsInterface) { throw new Exception(string.Format("未找到类型[{0}]名称[{0}]的注册节点", type.FullName, name)); } //未找到注册节点的非接口类型,则主动注册一个(不进行AOP规则适配,仅对可装配的属性进行匹配) Register(name, type, type, false, false); if (!BIND_DICTIONARY.TryGetValue(key, out bind)) { throw new Exception(string.Format("未找到类型[{0}]名称[{0}]的注册节点", type.FullName, name)); } } object result = null; bool singleton = bind.Issingleton; //如果是单例,则首先查找单例池 if (singleton && INSTANCE_DICTIONARY.TryGetValue(key, out result)) { return(result); } result = CreateInstance(key, singleton); if (result != null) { return(AppendProperties(result, bind, depth)); } lock (FUNC_DICTIONARY) { result = CreateInstance(key, singleton); if (result != null) { return(AppendProperties(result, bind, depth)); } Type agentType = null; //如果注册的基类是非接口类型,则不适用AOP的规则,直接使用注册的实现类型来创建代理 if (!bind.BindType.IsInterface || (bind.BindType.IsInterface && !HasAspectAttribute(bind.ToType))) { agentType = CreateAgentTypeByClass(bind.BindType); //创建代理类 } else { agentType = CreateAgentTypeByInterface(bind.BindType, bind.ToType); //创建代理类 //更新BindElement lock (bind) bind.AgentType = agentType; } //创建生成类实例的委托 var func = EmitHelper.CreateFunc(agentType); //生成本次的新的实例 result = func(); //加入缓存 FUNC_DICTIONARY.Add(key, func); //处理单例 if (singleton) { lock (INSTANCE_DICTIONARY) { object instance = null; if (INSTANCE_DICTIONARY.TryGetValue(key, out instance)) { return(instance); } else { INSTANCE_DICTIONARY.Add(key, result); } } } } return(AppendProperties(result, bind, depth)); }