/// Add a command module from a <see cref="Type"/>.
/// </summary>
/// <typeparam name="T">The type of module</typeparam>
/// <param name="services">An IServiceProvider for your dependency injection solution, if using one - otherwise, pass null</param>
/// <returns>A built module</returns>
/// <typeparam name="T">The type of module.</typeparam>
/// <param name="services">An <see cref="IServiceProvider"/> for your dependency injection solution, if using one - otherwise, pass <see langword="null"/>. </param>
/// <returns>A built module.</returns>
public Task<ModuleInfo> AddModuleAsync<T>(IServiceProvider services) => AddModuleAsync(typeof(T), services);
public async Task<ModuleInfo> AddModuleAsync(Type type, IServiceProvider services)
{
@@ -127,7 +127,7 @@ namespace Discord.Commands
var typeInfo = type.GetTypeInfo();
if (_typedModuleDefs.ContainsKey(type))
throw new ArgumentException($"This module has already been added.");
throw new ArgumentException("This module has already been added.");
var module = (await ModuleClassBuilder.BuildAsync(this, services, typeInfo).ConfigureAwait(false)).FirstOrDefault();
@@ -144,11 +144,11 @@ namespace Discord.Commands
}
}
/// <summary>
/// Add command modules from an assembly
/// Add command modules from an <see cref="Assembly"/>.
/// <param name="services">An <see cref="IServiceProvider"/> for your dependency injection solution, if using one - otherwise, pass <see langword="null"/>.</param>
/// <returns>A collection of built modules.</returns>
public async Task<IEnumerable<ModuleInfo>> AddModulesAsync(Assembly assembly, IServiceProvider services)
/// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type.
/// If <typeparamref name="T"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> will also be added.
/// If a default <see cref="TypeReader"/> exists for <typeparamref name="T"/>, a warning will be logged and the default <see cref="TypeReader"/> will be replaced.
/// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type.
/// <para>
/// If <typeparamref name="T"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> will also be added.
/// </para>
/// <para>
/// If a default <see cref="TypeReader"/> exists for <typeparamref name="T"/>, a warning will be logged and the default <see cref="TypeReader"/> will be replaced.
/// </para>
/// </summary>
/// <typeparam name="T">The object type to be read by the <see cref="TypeReader"/>.</typeparam>
/// <param name="reader">An instance of the <see cref="TypeReader"/> to be added.</param>
public void AddTypeReader<T>(TypeReader reader)
=> AddTypeReader(typeof(T), reader);
/// <summary>
/// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type.
/// If <paramref name="type"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> for the value type will also be added.
/// If a default <see cref="TypeReader"/> exists for <paramref name="type"/>, a warning will be logged and the default <see cref="TypeReader"/> will be replaced.
/// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type.
/// <para>
/// If <paramref name="type"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> for the value type will also be added.
/// </para>
/// <para>
/// If a default <see cref="TypeReader"/> exists for <paramref name="type"/>, a warning will be logged and the default <see cref="TypeReader"/> will be replaced.
/// </para>
/// </summary>
/// <param name="type">A <see cref="Type"/> instance for the type to be read.</param>
/// <param name="reader">An instance of the <see cref="TypeReader"/> to be added.</param>
@@ -250,12 +258,14 @@ namespace Discord.Commands
{
if (_defaultTypeReaders.ContainsKey(type))
_ = _cmdLogger.WarningAsync($"The default TypeReader for {type.FullName} was replaced by {reader.GetType().FullName}." +
$"To suppress this message, use AddTypeReader<T>(reader, true).");
"To suppress this message, use AddTypeReader<T>(reader, true).");
AddTypeReader(type, reader, true);
}
/// <summary>
/// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type.
/// If <typeparamref name="T"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> will also be added.
/// <para>
/// If <typeparamref name="T"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> will also be added.
/// </para>
/// </summary>
/// <typeparam name="T">The object type to be read by the <see cref="TypeReader"/>.</typeparam>
/// <param name="reader">An instance of the <see cref="TypeReader"/> to be added.</param>
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI", nameof(Url));
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI.", nameof(Url));
_url = value;
}
}
@@ -67,7 +67,7 @@ namespace Discord
get => _thumbnail?.Url;
set
{
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI", nameof(ThumbnailUrl));
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI.", nameof(ThumbnailUrl));
_thumbnail = new EmbedThumbnail(value, null, null, null);
}
}
@@ -77,7 +77,7 @@ namespace Discord
get => _image?.Url;
set
{
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI", nameof(ImageUrl));
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI.", nameof(ImageUrl));
_image = new EmbedImage(value, null, null, null);
}
}
@@ -87,7 +87,7 @@ namespace Discord
get => _fields;
set
{
if (value == null) throw new ArgumentNullException("Cannot set an embed builder's fields collection to null", nameof(Fields));
if (value == null) throw new ArgumentNullException(nameof(Fields), "Cannot set an embed builder's fields collection to null.");
if (value.Count > MaxFieldCount) throw new ArgumentException($"Field count must be less than or equal to {MaxFieldCount}.", nameof(Fields));
_fields = value;
}
@@ -271,7 +271,7 @@ namespace Discord
public Embed Build()
{
if (Length > MaxEmbedLength)
throw new InvalidOperationException($"Total embed length must be less than or equal to {MaxEmbedLength}");
throw new InvalidOperationException($"Total embed length must be less than or equal to {MaxEmbedLength}.");
var fields = ImmutableArray.CreateBuilder<EmbedField>(Fields.Count);
for (int i = 0; i < Fields.Count; i++)
@@ -294,7 +294,7 @@ namespace Discord
get => _name;
set
{
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException($"Field name must not be null, empty or entirely whitespace.", nameof(Name));
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("Field name must not be null, empty or entirely whitespace.", nameof(Name));
if (value.Length > MaxFieldNameLength) throw new ArgumentException($"Field name length must be less than or equal to {MaxFieldNameLength}.", nameof(Name));
_name = value;
}
@@ -354,7 +354,7 @@ namespace Discord
get => _url;
set
{
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI", nameof(Url));
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI.", nameof(Url));
_url = value;
}
}
@@ -363,7 +363,7 @@ namespace Discord
get => _iconUrl;
set
{
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI", nameof(IconUrl));
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI.", nameof(IconUrl));
_iconUrl = value;
}
}
@@ -409,7 +409,7 @@ namespace Discord
get => _iconUrl;
set
{
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI", nameof(IconUrl));
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI.", nameof(IconUrl));
Thank you for your continuous support to the Openl Qizhi Community AI Collaboration Platform. In order to protect your usage rights and ensure network security, we updated the Openl Qizhi Community AI Collaboration Platform Usage Agreement in January 2024. The updated agreement specifies that users are prohibited from using intranet penetration tools. After you click "Agree and continue", you can continue to use our services. Thank you for your cooperation and understanding.