public ISettingElement GetSettingElement(IConfigurationFileElement requestingConfigurationFileElement, string settingName) { if (string.IsNullOrEmpty(settingName)) { throw new ConfigurationParseException(requestingConfigurationFileElement, "The setting name cannot be empty."); } ISettingElement _settingElement = null; if (requestingConfigurationFileElement.OwningPluginElement != null) { _settingElement = requestingConfigurationFileElement.GetPluginSetupElement().SettingsElement?.GetSettingElement(settingName); } if (_settingElement == null) { _settingElement = requestingConfigurationFileElement.Configuration.SettingsElement?.GetSettingElement(settingName); } if (_settingElement == null) { throw new ConfigurationParseException(requestingConfigurationFileElement, $"Setting with name '{settingName}' was not found."); } return(_settingElement); }
public static void LogElementDisabledWarning([NotNull] IConfigurationFileElement configurationFileElement, [CanBeNull] IAssembly assembly, bool logInfo = false) { if (configurationFileElement.Enabled) { return; } // Lets see if this element is a child of PluginSetup element, in which case we do not want to log any warning // since we already logged a warning for plugin is disabled. if (configurationFileElement.GetPluginSetupElement() != null) { return; } var warning = new StringBuilder(); warning.AppendLine($"Element '{configurationFileElement}' is disabled."); var pluginElement = assembly?.Plugin ?? configurationFileElement.OwningPluginElement; if (pluginElement != null && !pluginElement.Enabled) { warning.AppendLine($" To enable this element enable the plugin '{pluginElement.Name}'."); } if (logInfo) { LogHelper.Context.Log.Info(warning.ToString()); } else { LogHelper.Context.Log.Warn(warning.ToString()); } }
public static INamedTypeDefinitionElement GetTypeDefinition([NotNull] this IConfigurationFileElement configurationFileElement, [NotNull] string alias) { var pluginSetupElement = configurationFileElement.GetPluginSetupElement(); var typeDefinitions = pluginSetupElement != null && pluginSetupElement.TypeDefinitions != null ? pluginSetupElement.TypeDefinitions : configurationFileElement.Configuration.TypeDefinitions; return(typeDefinitions?.GetTypeDefinition(alias)); }
public void Validate(IConfigurationFileElement requestingConfigurationFileElement, ITypeInfo typeInfo) { var uniquePluginTypes = typeInfo.GetUniquePluginTypes(); if (uniquePluginTypes.Count == 0) { return; } if (uniquePluginTypes.Count > 1) { var errorMessage = new StringBuilder(); errorMessage.Append($"Type '{typeInfo.TypeCSharpFullName}' uses types '{uniquePluginTypes[0].TypeCSharpFullName}' and '{uniquePluginTypes[1].TypeCSharpFullName}'"); errorMessage.Append($" which are defined in assemblies '{uniquePluginTypes[0].Assembly}' and '{uniquePluginTypes[1].Assembly}' that belong to different plugins '{uniquePluginTypes[0].Assembly.Plugin.Name}' and '{uniquePluginTypes[1].Assembly.Plugin.Name}'."); errorMessage.Append(" Generic types cannot use types from different plugins."); throw new ConfigurationParseException(requestingConfigurationFileElement, errorMessage.ToString()); } // If we got here, we have only one plugin type. var pluginTypeInfo = uniquePluginTypes[0]; var pluginSetupElement = requestingConfigurationFileElement.GetPluginSetupElement(); if (pluginSetupElement == null) { // Check the parents, until we find an element which allows the plugin type. var currElement = requestingConfigurationFileElement; var pluginToLookFor = uniquePluginTypes[0].Assembly.Plugin; while (!(currElement is IConfiguration)) { if (currElement is ITypedItem typedItem && (currElement.Parent is ICanHaveChildElementsThatUsePluginTypeInNonPluginSection || currElement.Parent is ValueInitializerElementDecorator parentValueInitializerElementDecorator && parentValueInitializerElementDecorator.DecoratedValueInitializerElement is ICanHaveChildElementsThatUsePluginTypeInNonPluginSection)) { if (currElement == requestingConfigurationFileElement) { // If requestingConfigurationFileElement is implementation element (or parameter serializer element, or collection item), // it can use any plugin type. return; } var parentUniquePluginTypes = typedItem.ValueTypeInfo.GetUniquePluginTypes(); if (parentUniquePluginTypes.FirstOrDefault(x => x.Assembly.Plugin == pluginToLookFor) != null) { // If we found a parent service implemenation or collection item, that uses the same plugin, we are fine. return; } } currElement = currElement.Parent; } // If we got here, it means the type cannot be used in this context var errorMessage = new StringBuilder(); errorMessage.Append($"Type '{typeInfo.TypeCSharpFullName}'"); if (typeInfo.GenericTypeParameters.Count > 0) { errorMessage.Append($" uses type '{pluginTypeInfo.TypeCSharpFullName}' which"); } errorMessage.AppendLine($" is defined in assembly '{pluginTypeInfo.Assembly.Alias}' that belongs to plugin '{pluginTypeInfo.Assembly.Plugin.Name}'."); errorMessage.AppendLine("Types that belong to plugins cannot be used in this context."); errorMessage.AppendLine($"Types that belong to plugins can be used either in elements immediately under some specific elements, such as {ConfigurationFileElementNames.Service}, {ConfigurationFileElementNames.ParameterSerializers}, or {ConfigurationFileElementNames.Collection}, or "); errorMessage.AppendLine($"these types can be used anywhere else in a tree below elements that use the same plugin type, and which are immediately under these elements (i.e., elements {ConfigurationFileElementNames.Service}, {ConfigurationFileElementNames.ParameterSerializers}, etc.)."); errorMessage.AppendLine("See the documentation at https://iocconfiguration.readthedocs.io/en/latest/xml-configuration-file/plugins.html for more details."); throw new ConfigurationParseException(requestingConfigurationFileElement, errorMessage.ToString()); } if (pluginTypeInfo.Assembly.Plugin != pluginSetupElement.Plugin) { var errorMessage = new StringBuilder(); errorMessage.Append($"Type '{typeInfo.TypeCSharpFullName}'"); if (typeInfo.GenericTypeParameters.Count > 0) { errorMessage.Append($" uses type '{pluginTypeInfo.TypeCSharpFullName}' which"); } errorMessage.AppendLine($" is defined in assembly '{pluginTypeInfo.Assembly.Alias}' that does not belong plugin '{pluginSetupElement.Plugin.Name}'."); errorMessage.Append($"Assembly '{pluginTypeInfo.Assembly.Alias}' belongs to plugin '{pluginTypeInfo.Assembly.Plugin.Name}'."); throw new ConfigurationParseException(requestingConfigurationFileElement, errorMessage.ToString()); } }