ASP .NET core 3.0 dependency injection throws System.InsufficientExecutionStackException

Viewed 691

I have a strange problem with the NET core dependency injection. When I'm trying to register a service, InsufficientExecutionStackException exception is thrown. What does this mean in this context? This is how I register the services (third line throws the exception):

        var connectionStr = Configuration.GetValue<string>("databaseConnectionString");
        services.AddSingleton<IDatabaseService>(s => new MySqlDatabaseService(connectionStr));
        services.AddSingleton<IUserService>(s => new UserService(s.GetRequiredService<IUserRepository>(), secret, s.GetRequiredService<IAchievementService>()));//this line throws the exception
        services.AddSingleton<IAchievementService, AchievementService>();
        services.AddSingleton<IUserRepository, UserRepository>();
        services.AddSingleton<IAchievementRepository, AchievementRepository>();
        services.AddSingleton<IUserRequestService, UserRequestService>();
        services.AddSingleton<AppSettingsService>();

Two services are injected in UserService class. These are the constructors of those:

    public UserService(IUserRepository userRepository, string secret, IAchievementService achievementService)
    {
        this.achievementService = achievementService;
        this.userRepository = userRepository;
        this.secret = secret;
    }

UserRepository:

    public UserRepository(IDatabaseService databaseService)
    {
        this.databaseService = databaseService;
    }

AchievementService:

        public AchievementService(IAchievementRepository achievementRepository, IUserService userService)
    {
        this.achievementRepository = achievementRepository;
        this.userService = userService;
        this.userRequestService = userRequestService;
    }

Another strange thing is that if I click "View details" from the Exception windows (I'm using Visual studio 2019) the debugger crashed and doesn't show anything.

1 Answers

It looks like you have a circular dependence between UserService and AchievementService. It's impossible for dotnet dependency injection to create an instance of the UserService without an instance of AchievementService. But to create an instance of AchievementService, you need an instance of UserService. So you're stuck in an infinite loop.

You should try to avoid this situation by removing the dependency. Do both services really need a dependency to the other one?

If it's not possible, you can try to use Lazy<Service> instead of just Service.

private readonly Lazy<IAchievementService> lazyAchievementService;

public UserService(Lazy<IAchievementService> lazyAchievementService, /*...*/)
{
    this.lazyAchievementService = lazyAchievementService;
    // ...
}

public void SomeFunction()
{
    var achievementService = lazyAchievementService.Value;
    achievementService.DoSomething();
}

This should allow you to create both class.

Related