According to user Ralf's comments, it's ideal to use the AddTransient<T> (or AddScoped<T>, AddSingleton<T> depending on what you want to achieve) overload registration method that takes a delegate. As a delegate you can call your static "factory" method and in this way the dependecy injection system will create a Example instance. Note that your factory method returns a Task. You need to make sure how your dependency injection system handles such delegates. You may need to do all the registration asynchronously, or wait (e.g. wait()) for a Task from a factory method.
services.AddTransient<Example>(_ => CreateInstance(provider))
Additionally...
You can also "cover" all this mechanics with the help of Extension Methods, in order to provide a clean and simple API. Your Example class could then be internal and only the be a registration extension-method would be public. Keep in mind, however, that it also strongly depends on the structure of your project. Simple example:
// Extensions method class
public static IServiceCollectionExtensions
{
public static IServiceCollection AddExample(this IServiceCollection services)
{
// Resolve your DbContextProvider here via IServiceCollection
return services.AddTransient<Example>(_ => CreateInstance(provider))
}
}
// The place you register the services
services.AddExample()