The difference can be seen in the source code.
The first one is the IServiceCollection interface, a core interface of the dependency injection.
public interface IServiceCollection : IList<ServiceDescriptor>
{
}
IServiceCollection is just a list of ServiceDescriptor objects. ServiceDescriptor describes the information of the injected types.
Based on this interface, the two methods Add and Replace can be discussed.
public static IServiceCollection Add(
this IServiceCollection collection,
ServiceDescriptor descriptor)
{
...
collection.Add(descriptor);
return collection;
}
public static IServiceCollection Replace(
this IServiceCollection collection,
ServiceDescriptor descriptor)
{
...
// Remove existing
int count = collection.Count;
for (int i = 0; i < count; i++)
{
if (collection[i].ServiceType == descriptor.ServiceType)
{
collection.RemoveAt(i);
break;
}
}
collection.Add(descriptor);
return collection;
}
Add just pushes the service descriptor into the list, while Replace firstly checks and deletes the descriptors in the list with the same service type, and finally add the current descriptor to the list.
Therefore, the time complexities of these two methods are different. The time complexity of Add in most cases is O(1), while Replace is O(n) (traverse the list). However, Add does not guarantee that the added descriptor is unique, but Replace will delete the descriptors with the same service type and add the current one.