diff --git a/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs b/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs index e9ce9eb86..1dd66cc77 100644 --- a/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs +++ b/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs @@ -291,7 +291,7 @@ namespace Discord.Commands //We dont have a cached type reader, create one reader = ReflectionUtils.CreateObject(typeReaderType.GetTypeInfo(), service, services); - service.AddTypeReader(paramType, reader); + service.AddTypeReader(paramType, reader, false); return reader; } diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs index f4fbcf8b2..7c7cdf7c5 100644 --- a/src/Discord.Net.Commands/CommandService.cs +++ b/src/Discord.Net.Commands/CommandService.cs @@ -215,10 +215,11 @@ namespace Discord.Commands return true; } - //Type Readers + //Type Readers /// /// Adds a custom to this for the supplied object type. /// If is a , a will also be added. + /// If a default exists for , a warning will be logged and the default will be replaced. /// /// The object type to be read by the . /// An instance of the to be added. @@ -226,17 +227,53 @@ namespace Discord.Commands => AddTypeReader(typeof(T), reader); /// /// Adds a custom to this for the supplied object type. - /// If is a , a for the value type will also be added. + /// If is a , a for the value type will also be added. + /// If a default exists for , a warning will be logged and the default will be replaced. /// /// A instance for the type to be read. /// An instance of the to be added. public void AddTypeReader(Type type, TypeReader reader) { - var readers = _typeReaders.GetOrAdd(type, x => new ConcurrentDictionary()); - readers[reader.GetType()] = reader; + if (_defaultTypeReaders.ContainsKey(type)) + _cmdLogger.WarningAsync($"The default TypeReader for {type.FullName} was replaced by {reader.GetType().FullName}. To suppress this message, use the overload that has a Boolean to replace the default one and pass true.").GetAwaiter().GetResult(); + AddTypeReader(type, reader, true); + } + /// + /// Adds a custom to this for the supplied object type. + /// If is a , a will also be added. + /// + /// The object type to be read by the . + /// An instance of the to be added. + /// If should replace the default for if one exists. + public void AddTypeReader(TypeReader reader, bool replaceDefaultTypeReader) + => AddTypeReader(typeof(T), reader, replaceDefaultTypeReader); + /// + /// Adds a custom to this for the supplied object type. + /// If is a , a for the value type will also be added. + /// + /// A instance for the type to be read. + /// An instance of the to be added. + /// If should replace the default for if one exists. + public void AddTypeReader(Type type, TypeReader reader, bool replaceDefaultTypeReader) + { + if (replaceDefaultTypeReader && _defaultTypeReaders.ContainsKey(type)) + { + _defaultTypeReaders.AddOrUpdate(type, reader, (k, v) => reader); + if (type.GetTypeInfo().IsValueType) + { + var nullableType = typeof(Nullable<>).MakeGenericType(type); + var nullableReader = NullableTypeReader.Create(type, reader); + _defaultTypeReaders.AddOrUpdate(nullableType, nullableReader, (k, v) => nullableReader); + } + } + else + { + var readers = _typeReaders.GetOrAdd(type, x => new ConcurrentDictionary()); + readers[reader.GetType()] = reader; - if (type.GetTypeInfo().IsValueType) - AddNullableTypeReader(type, reader); + if (type.GetTypeInfo().IsValueType) + AddNullableTypeReader(type, reader); + } } internal void AddNullableTypeReader(Type valueType, TypeReader valueTypeReader) {