(I'm ignoring the AuthenticationService for now because it only muddles the issue - what you have is a simple circular dependency between two services - Exception and Email).
The best way to solve these circular dependency issues is by using a layer of interfaces and a repository.
Lets say you have two classes, EmailService
and ExceptionService
. They can't reference each other's DLL, so what you do, you create a third assembly, Interfaces
, and create two interfaces for them, IEmailService
and IExceptionService
. Now your two classes can both reference only that shared Interfaces assembly.
Using some sort of Inversion of Control mechanism, your EmailService
gets a reference to a IExceptionService
, and vice versa, and thus the circle is broken.
One simple IoC mechanism is the Service Locator pattern. Create this (simplified) object:
public class ServiceLocator
{
public static IEmailService EmailService {get;set;}
public static IExceptionService ExceptionService {get;set;}
}
Now your EmailService, on startup, can register itself with the ServiceLocator, and allow other classes to get a reference to it, without having a dependency on its assembly.
Of course, most IoC solutions have a bit more to them than that, but that's the basic idea - prevent circular dependencies by extracting shared interfaces into a shared assembly, and reference only that.