public ITypeInfo GetTypeInfo(IConfigurationFileElement requestingConfigurationFileElement, string typeAttributeName, string assemblyAttributeName, string typeRefAttributeName, IEnumerable <ITypeInfo> genericTypeParameters) { ITypeInfo tryGetKnownTypeInfo() { // Lets have this in a block, so that typeInfo is not accessible in the rst of the code. if (TryGetPrimitiveType(requestingConfigurationFileElement, out var typeInfo)) { return(typeInfo); } if (requestingConfigurationFileElement.HasAttribute(typeRefAttributeName)) { if (requestingConfigurationFileElement.HasAttribute(typeAttributeName) || requestingConfigurationFileElement.HasAttribute(assemblyAttributeName)) { throw new ConfigurationParseException(requestingConfigurationFileElement, $"Attributes '{typeAttributeName}' and '{assemblyAttributeName}' cannot be used to specify a type, if attribute '{typeRefAttributeName}' is used."); } var typeRefAttributeValue = requestingConfigurationFileElement.GetAttributeValue(typeRefAttributeName); var typeDefinition = requestingConfigurationFileElement.GetTypeDefinition(typeRefAttributeValue); if (typeDefinition?.ValueTypeInfo == null) { throw new ConfigurationParseException(requestingConfigurationFileElement, $"Invalid value of attribute '{typeRefAttributeName}'. Type definition with alias '{typeRefAttributeValue}' was not found in section '{ConfigurationFileElementNames.TypeDefinitions}'."); } return(typeDefinition?.ValueTypeInfo); } return(null); } var typeInfo2 = tryGetKnownTypeInfo(); if (typeInfo2 != null) { _pluginAssemblyTypeUsageValidator.Validate(requestingConfigurationFileElement, typeInfo2); return(typeInfo2); } if (!requestingConfigurationFileElement.HasAttribute(typeAttributeName)) { throw new ConfigurationParseException(requestingConfigurationFileElement, $"A value for either '{typeRefAttributeName}' or '{typeAttributeName}' should be provided. If attribute '{typeAttributeName}' is present, an optional attribute '{assemblyAttributeName}' value can be provided as well, to enforce that the type is in specified assembly."); } var typeAttributeValue = requestingConfigurationFileElement.GetAttributeValue <string>(typeAttributeName); return(GetTypeInfoFromTypeFullName(requestingConfigurationFileElement, typeAttributeValue, genericTypeParameters, typeAttributeValue, assemblyAttributeName)); }
private ITypeInfo GetTypeInfo2([NotNull] IConfigurationFileElement requestingConfigurationFileElement, [NotNull] ITypeData typeData, [NotNull] string assemblyAttributeName, [NotNull][ItemNotNull] IReadOnlyList <ITypeInfo> genericTypeParametersList) { IAssembly assembly = null; if (assemblyAttributeName != null && requestingConfigurationFileElement.HasAttribute(assemblyAttributeName)) { assembly = Helpers.GetAssemblySettingByAssemblyAlias(requestingConfigurationFileElement, requestingConfigurationFileElement.GetAttributeValue <string>(assemblyAttributeName)); } string typeFullNameWithGenericParameters; { var typeFullNameWithGenericParametersStrBldr = new StringBuilder(); if (genericTypeParametersList.Count > 0) { typeFullNameWithGenericParametersStrBldr.Append($"{typeData.TypeFullNameWithoutGenericParameters}<{string.Join(",", genericTypeParametersList.Select(x => x.TypeCSharpFullName))}>"); } else { typeFullNameWithGenericParametersStrBldr.Append(typeData.TypeFullNameWithoutGenericParameters); } if (typeData.IsArray) { typeFullNameWithGenericParametersStrBldr.Append("[]"); } typeFullNameWithGenericParameters = typeFullNameWithGenericParametersStrBldr.ToString(); } System.Reflection.Assembly assemblyToLoadTypeFrom = null; if (assembly != null) { assemblyToLoadTypeFrom = LoadAssembly(assembly); } var lastIndexOfDotInType = typeData.TypeFullNameWithoutGenericParameters.LastIndexOf('.'); string typePotentialNamespace = lastIndexOfDotInType > 0 && lastIndexOfDotInType < typeData.TypeFullNameWithoutGenericParameters.Length - 1 ? typeData.TypeFullNameWithoutGenericParameters.Substring(0, lastIndexOfDotInType) : null; IEnumerable <IoC.Configuration.IAssembly> assembliesToSearch; if (assembly != null) { assembliesToSearch = new IoC.Configuration.IAssembly[] { assembly }; } else { if (typePotentialNamespace != null) { var assembliesThatArePartOfNamespace = new List <IoC.Configuration.IAssembly>(); var assembliesThatContainNamespacePart = new List <IoC.Configuration.IAssembly>(); var assembliesThatDoNotContainNamespacePart = new List <IoC.Configuration.IAssembly>(); foreach (var currentAssembly in requestingConfigurationFileElement.Configuration.Assemblies.AllAssembliesIncludingAssembliesNotInConfiguration) { if (typePotentialNamespace.StartsWith(currentAssembly.Name)) { assembliesThatArePartOfNamespace.Add(currentAssembly); } else { var indexOfDot = currentAssembly.Name.IndexOf('.'); if (indexOfDot >= 0 && typePotentialNamespace.StartsWith( string.Concat(currentAssembly.Name.Substring(0, indexOfDot), "."))) { assembliesThatContainNamespacePart.Add(currentAssembly); } else { assembliesThatDoNotContainNamespacePart.Add(currentAssembly); } } } var assembliesToSearchList = new List <IoC.Configuration.IAssembly>( assembliesThatArePartOfNamespace.Count + assembliesThatContainNamespacePart.Count + assembliesThatDoNotContainNamespacePart.Count); assembliesToSearchList.AddRange(assembliesThatArePartOfNamespace); assembliesToSearchList.AddRange(assembliesThatContainNamespacePart); assembliesToSearchList.AddRange(assembliesThatDoNotContainNamespacePart); assembliesToSearch = assembliesToSearchList; } else { assembliesToSearch = requestingConfigurationFileElement.Configuration.Assemblies.AllAssembliesIncludingAssembliesNotInConfiguration; } } if (!_typeFullNameToTypeInfo.TryGetValue(typeFullNameWithGenericParameters, out var typeInfo)) { ITypeInfo tryFindTypeInAssemblies(bool tryLocalType) { if (tryLocalType && typePotentialNamespace == null) { return(null); } var internalTypeNameStrBldr = new StringBuilder(); if (tryLocalType) { internalTypeNameStrBldr.Append($"{typePotentialNamespace}+{typeData.TypeFullNameWithoutGenericParameters.Substring(lastIndexOfDotInType + 1)}"); } else { internalTypeNameStrBldr.Append(typeData.TypeFullNameWithoutGenericParameters); } if (genericTypeParametersList.Count > 0) { internalTypeNameStrBldr.Append($"`{genericTypeParametersList.Count}"); } var internalTypeName = internalTypeNameStrBldr.ToString(); foreach (var currAssembly in assembliesToSearch) { System.Reflection.Assembly currAssemblyToLoadTypeFrom; if (currAssembly == assembly) { currAssemblyToLoadTypeFrom = assemblyToLoadTypeFrom; } else { if (currAssembly is IAssembly assemblyElement) { currAssemblyToLoadTypeFrom = LoadAssembly(assemblyElement); } else { currAssemblyToLoadTypeFrom = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(x => currAssembly.Name.Equals(x.GetName().Name, StringComparison.OrdinalIgnoreCase)); if (currAssemblyToLoadTypeFrom == null) { throw new ConfigurationParseException(requestingConfigurationFileElement, $"Assembly '{currAssembly.Name}' is not loaded. There should be an error in code, since this scenario should never happen."); } } } var loadedType = currAssemblyToLoadTypeFrom.GetType(internalTypeName, false, false); if (loadedType != null) { if (genericTypeParametersList.Count > 0) { internalTypeNameStrBldr.Append('['); for (var i = 0; i < genericTypeParametersList.Count; ++i) { var genericTypeParameterType = genericTypeParametersList[i]; if (i > 0) { internalTypeNameStrBldr.Append(", "); } internalTypeNameStrBldr.AppendFormat($"[{genericTypeParameterType.TypeInternalFullNameWithAssembly}]"); } internalTypeNameStrBldr.Append(']'); internalTypeName = internalTypeNameStrBldr.ToString(); loadedType = currAssemblyToLoadTypeFrom.GetType(internalTypeName, false, false); } if (loadedType != null) { if (typeData.IsArray) { return(TypeInfo.CreateArrayTypeInfo(loadedType, currAssembly, genericTypeParametersList)); } return(TypeInfo.CreateNonArrayTypeInfo(loadedType, currAssembly, genericTypeParametersList)); } } } return(null); } typeInfo = tryFindTypeInAssemblies(false); if (typeInfo == null) { typeInfo = tryFindTypeInAssemblies(true); } if (typeInfo == null) { var searchedAssembliesDetails = new StringBuilder(); searchedAssembliesDetails.Append($"Type '{typeFullNameWithGenericParameters}' was not found"); if (assembly != null) { searchedAssembliesDetails.AppendLine($" in assembly '{assembly.Name}' with alias '{assembly.Alias}' at the path '{assembly.AbsolutePath}'."); searchedAssembliesDetails.AppendLine($"To fix the problem, either specify a correct assembly, or remove the attribute '{assemblyAttributeName}' from element '{requestingConfigurationFileElement.ElementName}' to look for the type in all assemblies specified in element 'iocConfiguration/{ConfigurationFileElementNames.Assemblies}'."); } else { searchedAssembliesDetails.AppendLine("."); searchedAssembliesDetails.AppendLine($"Make sure that the assembly where the type is defined is included in element iocConfiguration/{ConfigurationFileElementNames.Assemblies}'."); searchedAssembliesDetails.Append(GetSearchedAssembliesText(assembliesToSearch)); } throw new ConfigurationParseException(requestingConfigurationFileElement, searchedAssembliesDetails.ToString()); } _typeFullNameToTypeInfo[typeFullNameWithGenericParameters] = typeInfo; LogHelper.Context.Log.Info($"Loaded type '{typeInfo.TypeCSharpFullName}' from assembly '{typeInfo.Assembly.Name}' at '{typeInfo.Type.Assembly.Location}'."); } if (assembly != null && !typeInfo.Assembly.Name.Equals(assembly.Name)) { var errorMessage = new StringBuilder(); errorMessage.AppendLine($"Type '{typeInfo.TypeCSharpFullName}' was found in assembly '{typeInfo.Assembly.Name}'."); errorMessage.AppendLine($"The type is expected to be in assembly '{assembly.Name}'."); errorMessage.AppendLine($"Either remove the attribute '{assemblyAttributeName}' from element, or make sure that the type is defined only in assembly '{assembly.Name}' at '{assembly.AbsolutePath}'."); throw new ConfigurationParseException(requestingConfigurationFileElement, errorMessage.ToString()); } return(typeInfo); }