FranciscoFJM
FranciscoFJM

Reputation: 151

(Interface) A circular dependency was detected for the service of type

I have 2 interfaces:

public interface IPedidoService
{
    UsuarioDrogueria CUsuarioDrogueria(string userId, int idDrogueria);
    List<PedidoComboProducto> CPedidosCombosProductos(int idcombo, int idPedido);  
} 

public interface IEmailService
{
    void SendEmailAttachment(string email, string subject, string archive);
    void SendNotificationEmail(List<Pedido> pedidos, string email, Drogueria drog);
    void SendNotificationEmailADM(Pedido pedido) ;
}

I want to use the functions from IEmailService inside IPedidoService, so I inject it in its constructor when I create the respository.

public class PedidoService : IPedidoService
{
    private readonly IEmailService emailService;

    public PedidoService(IEmailService e)
    {
        this.emailService = e;
    }
}

Up until here everything works fine, but when I try to do reverse the roles (IPedidoService functions inside IEmailService):

public class EmailService : IEmailService
{
    private readonly IPedidoService pedidoSettings;

    public EmailService(IPedidoService p)
    {
        this.pedidoSettings = p;
    }
}

I end up getting this exception:

System.InvalidOperationException: A circular dependency was detected for the service of type
   'EnvioPedidos.Data.Abstract.IPedidoService'.
    EnvioPedidos.Data.Abstract.IPedidoService(EnvioPedidos.PedidoService) ->
    EnvioPedidos.Data.Abstract.IEmailService(EnvioPedidos.EmailService) ->
    EnvioPedidos.Data.Abstract.IPedidoService

Can anybody help me trace the issue here?

Upvotes: 2

Views: 6638

Answers (2)

Rena
Rena

Reputation: 36605

A simple way is to use Lazy<T> class which is based on this blog:

Custom extension method:

public static class LazyResolutionMiddlewareExtensions
{
    public static IServiceCollection AddLazyResolution(this IServiceCollection services)
    {
        return services.AddTransient(
            typeof(Lazy<>),
            typeof(LazilyResolved<>));
    }
}

public class LazilyResolved<T> : Lazy<T>
{
    public LazilyResolved(IServiceProvider serviceProvider)
        : base(serviceProvider.GetRequiredService<T>)
    {
    }
}

Configure in Startup.cs:

public void ConfigureServices(IServiceCollection services)
{           
    //services.AddSingleton<IPedidoService, PedidoService>();
    //services.AddSingleton<IEmailService, EmailService>();

    services.AddLazyResolution();
}

Change your implements class:

public class PedidoService : IPedidoService
{
    private readonly Lazy<IEmailService> emailService;

    public PedidoService(Lazy<IEmailService> e)
    {
        this.emailService = e;
    }

    //...
}
public class EmailService : IEmailService
{
    private readonly Lazy<IPedidoService> pedidoSettings;

    public EmailService(Lazy<IPedidoService> p)
    {
        this.pedidoSettings = p;
    }
    //...
}

Upvotes: 9

jawsofdoom
jawsofdoom

Reputation: 297

When you have 2 classes, they cannot reference each other by dependency injection. This is called a circular dependency, as shown by your error. You need a 3rd class that references both services and you can use the methods there.

public class PedidoService
{
    public PedidoService()
    {

    }
}

public class EmailService
{

    public EmailService()
    {

    }
}

public class Container
{
    private readonly EmailService emailService;
    private readonly PedidoService pedidoService;

    public Container(EmailService emailService, PedidoService pedidoService)
    {
        this.emailService = emailService;
        this.pedidoService = pedidoService;
    }
    //use the services here
}

Upvotes: 1

Related Questions