Example #1
0
        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));
    }
Example #4
0
        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());
            }
        }