private IocConstructorMetaData resolveConstructor(Constructor constructor) { var metaData = new IocConstructorMetaData(constructor); var parameters = constructor.Parameters.ToArray(); Array.Sort(parameters, (x, y) => x.Index.CompareTo(y.Index)); metaData.Parameters = new IocParameterMetaData[parameters.Length]; for (var i = 0; i < parameters.Length; i++) { metaData.Parameters[i] = new IocParameterMetaData(); metaData.Parameters[i].RelatedType = parameters[i].ParameterType; metaData.Parameters[i].Name = parameters[i].Name; metaData.Parameters[i].Index = i; if (parameters[i].Attributes.Contains(typeof(DefaultValueAttribute))) { metaData.Parameters[i].DefaultValue = parameters[i].Attributes.GetAttribute <DefaultValueAttribute>()[0].Value; } //default value given by '=',like call(string name='sss'); if (!metaData.Parameters[i].HasDefaultValue && parameters[i].ParameterInfo.HasDefaultValue) { metaData.Parameters[i].DefaultValue = parameters[i].ParameterInfo.DefaultValue; } if (parameters[i].Attributes.Contains(typeof(DefaultImplementAttribute))) { metaData.Parameters[i].Impl = parameters[i].Attributes.GetAttribute <DefaultImplementAttribute>()[0].Impl; } if (parameters[i].Attributes.Contains(typeof(FromConfigAttribute))) { metaData.Parameters[i].ConfigKey = parameters[i].Attributes.GetAttribute <FromConfigAttribute>()[0].ConfigKey; } if (parameters[i].Attributes.Contains(typeof(NotNullAttribute))) { metaData.Parameters[i].NotNull = true; } } return(metaData); }
public void Resolve(string path) { var dom = new XmlDocument(); dom.Load(path); var dic = new Dictionary <string, Type>(); //use to cache name type mapping foreach (var service in dom.GetDirect(x => x.Name == SERVICES)) //iterate in services element { var typeStr = service.GetAttribute(TYPE); if (typeStr == null)//has type attr { throw new RequirdAttributeNotFoundException("type tag is requird of service element!"); } else { var type = Type.GetType(typeStr);//try get type if (type == null) { throw new TypeNotFoundException($"{typeStr} is not found"); } var name = service.GetAttribute(REF); if (name != null) { dic.Add(name, type); } if (type.IsInterfaceOrAbstractClass())//abstrct class impl should be instructed { var impl = service.GetAttribute(IMPL); if (impl == null) { throw new RequirdAttributeNotFoundException($"abstract or interface ,the impl attribute should be instructed!"); } var typeimpl = Type.GetType(impl); if (typeimpl == null) { throw new TypeNotFoundException($"{impl} is not found!"); } if (typeimpl.IsInterfaceOrAbstractClass() || typeimpl.CanConvertTo(type))// { throw new NotImplementedException($"{typeimpl} is abstract or not implement {type}"); } _manager.SetImplementationMapping(type, typeimpl); } else { //base type info if (!_manager.ContainsKey(type)) { _resolver.Resolve(type); } _manager.TryGetValue(type, out var metaData); var scope = service.GetAttribute(SCOPE); if (scope != null) { if (Enum.TryParse <ServiceScope>(scope, out var scopeE)) { metaData.Scope = scopeE; } else { throw new AttributeValueIncorrectException($"property scope,the value is incorrect!"); } } //find matched constructor //every parameter's type attribute is required if ref not exist foreach (var constructor in service.GetDirect(ctr => ctr.Name == CONSTRUCTOR)) { var candidate = new MethodCadidate(); foreach (var parameter in constructor.GetDirect(para => para.Name == PARAMETER)) { var parameterCadidate = new ParameterCadidate(); var refer = parameter.GetAttribute(REF); if (dic.TryGetValue(refer, out var value)) { parameterCadidate.Type = value; } var paraTypeStr = parameter.GetAttribute(TYPE); if (TypeUtils.TryGetType(paraTypeStr, out var paraType)) { parameterCadidate.Type = paraType; } else { throw new TypeNotFoundException($"{paraTypeStr} of parameter is not found!"); } var paraTypeImplStr = parameter.GetAttribute(IMPL); if (TypeUtils.TryGetType(paraTypeImplStr, out var paraTypImpl)) { if (paraTypImpl.IsInterfaceOrAbstractClass()) { throw new NotImplementedException($"{paraTypImpl} is abstrct or interface"); } parameterCadidate.Impl = paraTypImpl; } else { throw new TypeNotFoundException($"{paraTypeImplStr} is not found!"); } if (paraType == null || paraTypImpl == null) { throw new RequirdAttributeNotFoundException("parameter type or implement type must be instruct"); } if (paraType != null && IMPL != null && !paraTypImpl.CanConvertTo(paraType)) { throw new NotImplementedException($"{paraTypImpl} not implement {paraType}"); } var notNull = parameter.GetAttribute(NOT_NULL); if (JasmineStringValueConvertor.TryGetValue <bool>(notNull, out var notNullValue)) { parameterCadidate.NullNable = notNullValue; } else { throw new AttributeValueIncorrectException($"{notNull} is incorrect!"); } var value1 = parameter.GetAttribute(VALUE); if (value1 != null) { parameterCadidate.DefaultValue = value1; } foreach (var defaultValue in parameter.GetDirect(def => def.Name == VALUE)) { parameterCadidate.DefaultValue = defaultValue.InnerText; } candidate.Parameters.Add(parameterCadidate); } var constructors = _typeCache.GetItem(type).Constructors; Constructor matcherConstructor = null; foreach (var ctr in constructors) { var parameters = ctr.Parameters.ToArray(); Array.Sort(parameters, (x, y) => x.Index.CompareTo(y.Index)); if (candidate.Parameters.Count == parameters.Length) { var i = 0; bool match = true; foreach (var para in candidate.Parameters) { if (para.HasImplemnt && para.Impl.CanConvertTo(parameters[i].ParameterType)) { match = true; } else if (para.Type.CanConvertTo(parameters[i].ParameterType)) { match = true; } else { match = false; break; } } if (match) { matcherConstructor = ctr; break; } } if (metaData.ConstrctorMetaData.Constructor.Equals(ctr)) { foreach (var item in metaData.ConstrctorMetaData.Parameters) { } } else { var constructorMetaData = new IocConstructorMetaData(ctr); } } } /*** * * */ foreach (var property in service.GetDirect(pt => pt.Name == PROPERTY)) { } foreach (var initiaMethod in service.GetDirect(init => init.Name == INITIA_METHOD)) { } foreach (var destroyMethod in service.GetDirect(des => des.Name == DESTROY_METHOD)) { } } } } }