Asp.Net Core: some services are not able to be constructed

Dung Do Tien Apr 16 2021 475

I'm a newbie in Asp.Net Core 3.1 and I'm studying DI(Dependency injection) 

I have some service to test the lifetime of DI like transient, scope and singleton as below:

public interface IOperation
{
    string GenGuid();
}

public interface IOperationTrans: IOperation
{
}

public interface IOperationScope: IOperation
{
    
}

public interface IOperationSingleton: IOperation
{
}


public class Operation : IOperationTrans, IOperationScope, IOperationSingleton
{
    public string GuideRandom;
    public Operation()
    {
        GuideRandom = Guid.NewGuid().ToString();
    }

    public string GenGuid()
    {
        return GuideRandom;
    }
}

And I created another service with name IHumanService as below:

public interface IHumanService
{
    string GetTrans();
    string GetScope();
    string GetSingleton();
}

public class HumanService : IHumanService
{
    private readonly IOperationTrans operationTrans;
    private readonly IOperationScope operationScope;
    private readonly IOperationSingleton operationSingleton;

    public HumanService(IOperationTrans operationTrans, IOperationScope operationScope, IOperationSingleton operationSingleton)
    {
        this.operationTrans = operationTrans;
        this.operationScope = operationScope;
        this.operationSingleton = operationSingleton;
    }
    public string GetScope()
    {
        return operationScope.GenGuid();
    }

    public string GetSingleton()
    {
        return operationSingleton.GenGuid();
    }

    public string GetTrans()
    {
        return operationTrans.GenGuid();
    }

    public string GetTrans1()
    {
        return operationTrans.GenGuid();
    }
}

And I register them in Startup.cs as below:

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<IOperationTrans, Operation>();
    services.AddScoped<IOperationScope, Operation>();
    services.AddSingleton<IOperationSingleton, Operation>();
    services.AddSingleton<IHumanService, HumanService>();
    services.AddControllersWithViews();
}

Finally, I use them in my controller as below:

public class HomeController : Controller
{
    private readonly IOperationTrans operationTrans;
    private readonly IOperationScope operationScope;
    private readonly IOperationSingleton operationSingleton;
    private readonly IHumanService humanService;
    public HomeController(IOperationTrans operationTrans, IOperationScope operationScope, IOperationSingleton operationSingleton, IHumanService humanService = null)
    {
        this.operationTrans = operationTrans;
        this.operationScope = operationScope;
        this.operationSingleton = operationSingleton;
        this.humanService = humanService;
    }

    public IActionResult Index()
    {
        DIModel model = new DIModel();
        model.TransProperty = operationTrans.GenGuid();
        model.TransProperty1 = humanService.GetTrans();
        model.ScopeProperty = operationScope.GenGuid();
        model.ScopeProperty1 = humanService.GetScope();
        model.SingletonProperty = operationSingleton.GenGuid();
        model.SingletonProperty1 = humanService.GetSingleton();
        return View(model);
    }
}

When I run the project I got an error : AggregateException: Some services are not able to be constructed 

An error occurred while starting the application.
AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: LearnDIExample.BSL.Human.IHumanService Lifetime: Singleton ImplementationType: LearnDIExample.BSL.Human.HumanService': Cannot consume scoped service 'LearnDIExample.BSL.Operation.IOperationScope' from singleton 'LearnDIExample.BSL.Human.IHumanService'.)
Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable<ServiceDescriptor> serviceDescriptors, ServiceProviderOptions options)

InvalidOperationException: Error while validating the service descriptor 'ServiceType: LearnDIExample.BSL.Human.IHumanService Lifetime: Singleton ImplementationType: LearnDIExample.BSL.Human.HumanService': Cannot consume scoped service 'LearnDIExample.BSL.Operation.IOperationScope' from singleton 'LearnDIExample.BSL.Human.IHumanService'.
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.ValidateService(ServiceDescriptor descriptor)

AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: LearnDIExample.BSL.Human.IHumanService Lifetime: Singleton ImplementationType: LearnDIExample.BSL.Human.HumanService': Cannot consume scoped service 'LearnDIExample.BSL.Operation.IOperationScope' from singleton 'LearnDIExample.BSL.Human.IHumanService'.)
Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable<ServiceDescriptor> serviceDescriptors, ServiceProviderOptions options)
Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options)
Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder)
Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter<TContainerBuilder>.CreateServiceProvider(object containerBuilder)
Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
Microsoft.Extensions.Hosting.HostBuilder.Build()
LearnDIExample.Program.Main(string[] args) in Program.cs
+
            CreateHostBuilder(args).Build().Run();

I really difficult to understand about DI, How can I resolve it?

Have 1 answer(s) found.
  • T

    Tran Quang Hung Apr 16 2021

    As your code, I can understand that: IHumanService is parent service it uses other services as IOperationTrans IOperationScope IOperationSingleton (three services are children)

    => You are registered for parent service is Singleton lifetime.

    => For 3 services contain both Singleton, Scope and Transient lifetimes.

    But dependency injection is NOT alow: 

    - Case 1:  Parent use Singleton and children use Scope.

    - Case 2: Parent use Scope and children use Singleton.

    SOLUTION

    Case 1: Change children from Scope to Singleton or Transient

    public void ConfigureServices(IServiceCollection services)
    {
        //..............
        services.AddSingleton<IOperationScope, Operation>();
        OR
        services.AddTransient<IOperationScope, Operation>();
        //..............
    }

    Case 2: Change service parent from Singleton to Scope or Transient

    public void ConfigureServices(IServiceCollection services)
    {
        //..............
        services.AddTransient<IHumanService, HumanService>();
        OR
        services.AddScoped<IHumanService, HumanService>();
        //..............
    }

    I hope it useful for you!!!

Leave An Answer
* NOTE: You need Login before leave an answer

* Type maximum 2000 characters.

* All comments have to wait approved before display.

* Please polite comment and respect questions and answers of others.

Popular Tips

X Close