2

Can't find proper way to inject internal class from separate library. Found solution for similar problem for Autofac, but can't find same one for embedded dependency injection mechanism.

My project structure looks like this:

Marketplace (asp.net) project:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMarketplaceDbContext();
    }
}

Business (library):

public static class DI
{
    public static IServiceCollection AddMarketplaceDbContext(
        this IServiceCollection services)
    {
        services.AddSingleton<DeviceHandler>(x =>
        {
            var context = x.GetRequiredService<MarketplaceContext>();
            return new DeviceHandler(context);
        });
        return services.AddDbContext<MarketplaceContext>(options =>
            options.UseNpgsql("connection_string"));
    }
}

public class DeviceHandler
{
    private readonly MarketplaceContext _context;

    internal DeviceHandler(MarketplaceContext marketplaceContext)
    {
        _context = marketplaceContext;
    }
}

internal class MarketplaceContext : DbContext
{
    public MarketplaceContext(DbContextOptions<MarketplaceContext> options)
        : base(options)
    {
    }
}

And that works, but if I try to inject DeviceHandler like this

services.AddSingleton<MarketplaceHandler>();

Then I'm getting

System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Business.Core.DeviceHandler Lifetime: Singleton ImplementationType: Business.Core.DeviceHandler': A suitable constructor for type 'Business.Core.DeviceHandler' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.)'

1 of 2 Inner Exceptions:

InvalidOperationException: Error while validating the service descriptor 'ServiceType: Business.Core.DeviceHandler Lifetime: Singleton ImplementationType: Business.Core.DeviceHandler': A suitable constructor for type 'Business.Core.DeviceHandler' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.

2 of 2 Inner Exceptions:

InvalidOperationException: A suitable constructor for type 'Business.Core.DeviceHandler' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.

Hope that anybody knows better (or proper) solution.

Steven
  • 166,672
  • 24
  • 332
  • 435
  • I think issue can be related to fact that `DeviceHandler` is registered as singleton and default lifetime for `AddDbContext` is `Scoped`, and you can't use scoped services in singletons, only other singleton and transient ones. – Guru Stron Apr 26 '21 at 20:42
  • Tried both `Scoped` and `Transient` - doesn't help. – Dmitriy Bobrovskiy Apr 26 '21 at 20:45
  • Note that `MarketplaceContext` became a [Captive Dependency](https://blog.ploeh.dk/2014/06/02/captive-dependency/) because you registered `DeviceHandler` as Singleton. – Steven Apr 27 '21 at 08:40

0 Answers0