I'm migrating a web application from the time where startup was used:
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
private static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
and then in Startup.cs
, I would have something like:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<MyService>();
}
MyService
looks like this:
public class MyService(MyData d) { }
public class MyData(int i) { }
I'm aware that this can not be resolved by DI, but I had the following code to handle this:
public static class ServiceProviderHelper
{
public static T ResolveWith<T, TData>(this IServiceProvider serviceProvider, TData
data) where TData : class
{
return ActivatorUtilities.CreateInstance<T>(serviceProvider, data);
}
}
and then somewhere call it like that:
var s = _serviceProvider.ResolveWith<MyService, MyData>(new MyData(6));
Now when I try to do it 'the new way':
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<MyService>();
var app = builder.Build(); // Ex here
I'm getting the following Exception:
'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: BlazorApp1.MyService Lifetime: Scoped ImplementationType: BlazorApp1.MyService': Unable to resolve service for type 'BlazorApp1.MyData' while attempting to activate 'BlazorApp1.MyService'.)'
Why does this happen and what can I do to fix it?
The call to AddScoped<MyService>
is redundant and should be removed.
It is redundant because the call to ActivatorUtilities.CreateInstance<T>
never uses that registration. The call to AddScoped<MyService>
is a separate registration, which is validated at application startup. That registration forces the DI Container to resolve all of MyService
's dependencies, which it can't, because MyData
isn't registered.
The solution, therefore, is to remove the registration of MyService
.
Reason this worked in the past is likely because you were using an old version of MS.DI that didn't support container validation. I think validation was added in .NET Core 3.