protected virtual void ValidateImplementationsAfterChildrenAdded() { foreach (var childElement in Children) { if (childElement is IServiceImplementationElement serviceImplementation) { if (!ServiceTypeInfo.Type.IsAssignableFrom(serviceImplementation.ValueTypeInfo.Type)) { throw new ConfigurationParseException(serviceImplementation, $"Implementation '{serviceImplementation.ValueTypeInfo.TypeCSharpFullName}' is not valid for service '{ServiceTypeInfo.TypeCSharpFullName}'.", this); } var disabledPluginTypeInfo = serviceImplementation.ValueTypeInfo.GetUniquePluginTypes().FirstOrDefault(x => !x.Assembly.Plugin.Enabled); if (disabledPluginTypeInfo == null) { // Note, the same implementation type might appear multiple times. // We do not want to prevent this, since each implementation might have different constructor parameters or injected properties. _serviceImplementations.Add(serviceImplementation); } else if (GetPluginSetupElement() == null) { var warningString = new StringBuilder(); warningString.Append($"Implementation '{serviceImplementation.ValueTypeInfo.TypeCSharpFullName}' will be ignored since it"); if (serviceImplementation.ValueTypeInfo.GenericTypeParameters.Count > 0) { warningString.Append($" uses type '{disabledPluginTypeInfo.TypeCSharpFullName}' which"); } warningString.Append($" is defined in assembly '{disabledPluginTypeInfo.Assembly.Alias}' that belongs to disabled plugin '{disabledPluginTypeInfo.Assembly.Plugin.Name}'."); LogHelper.Context.Log.Warn(warningString.ToString()); } } } // We might have a situation, when the only implementations are types in plugins, and all // plugins are disabled. In this case _serviceImplementations will be an empty enumeration, and that would be OK. if (_serviceImplementations.Count == 0) { LogHelper.Context.Log.WarnFormat(MessagesHelper.GetNoImplementationsForServiceMessage(ServiceTypeInfo.Type)); } else if (_serviceImplementations.Count > 1 && RegisterIfNotRegistered) { throw new ConfigurationParseException(this, MessagesHelper.GetMultipleImplementationsWithRegisterIfNotRegisteredOptionMessage($"attribute '{ConfigurationFileAttributeNames.RegisterIfNotRegistered}'")); } }