'Autofac Circular Component Dependency Detecte

2019-01-26 19:12发布

问题:

I am new to IoC and am using Autofac in my current project.

I have the following 2 classes:

public class UserService : IUserService
{
    private readonly IUserRepository _repo;
    private readonly IMailService _mailService;
    public UserService(IUserRepository repo, IMailService mailService)
    {
        _repo = repo;
        _mailService = mailService;
    }
}

public class MailService : IMailService
{
    private readonly IMailRepository _repo;
    private readonly IUserService _userService;
    public MailService(IMailRepository repo, IUserService userService)
    {
        _repo = repo;
        _userService = userService;
    }
}

Initially, my UserService class didn't require an instance of the MailService class, but now it does, and it's since introducing this into the UserService Constructor that this circular dependency error has arisen, and being a newbie, I'm not sure how to resolve this.

This is how my classes are currently registered in Autofac:

var builder = new ContainerBuilder();

// controllers                      
builder.RegisterControllers(Assembly.GetAssembly(typeof(UsersController)));

// register other classes
builder.RegisterType<UserRepository>().As<IUserRepository>();
builder.RegisterType<MailRepository>().As<IMailRepository>();
builder.RegisterType<UserService>().As<IUserService>();
builder.RegisterType<MailService>().As<IMailService>();

回答1:

If a UserService needs an IMailService and a MailService needs an IUserService you have a dependency loop. I see a couple of options:

  1. Does your UserService need an IMailService right away? Could you pass one in when it needs to send a message?

  2. Can either query the resolver on-demand - that is, don't pass IUserService to MailService in the constructor but rather code MailService to resolve IUserService when it needs it?



回答2:

Autofac has documentation on how to handle circular dependencies that might help here. You can get it to work if you follow the guidance there (which boils down to: make one of the dependencies a property rather than a constructor dependency).