I have a MyProject project where I have IMyService
interface and MyService
class that implements IMyService
. In Startup.cs class I dependency injection them:
// MyProject project | Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IMyService, MyService>();
}
Because MyService
has many dependencies (makes many REST calls to 3rd party etc.) I would like to create a stub version of it for development environment. I created new MyStubsProject that references to MyProject. And I implemented stub version of IMyService
to MyStubsProject:
// MyStubsProject project
public class MyStubService : IMyService
{
...
}
So now I want to add dependency injection to Startup.cs class:
// MyProject project | Startup.cs
public void ConfigureServices(IServiceCollection services)
{
if (isDevelopmentEnvironment)
services.AddScoped<IMyService, MyStubService>();
else
services.AddScoped<IMyService, MyService>();
}
But if I add that, there will be circular dependency between MyProject and MyStubsProject.
How should I implement reference to the class MyStubService
or MyStubsProject project in Startup.cs?
Circular dependencies can be introduced when implementing callback functionality. This can be avoided by applying design patterns like the observer pattern.
To resolve circular dependencies: Then there are three strategies you can use: Look for small pieces of code that can be moved from one project to the other. Look for code that both libraries depend on and move that code into a new shared library. Combine projectA and projectB into one library.
A cyclic dependency exists when a dependency of a service directly or indirectly depends on the service itself. For example, if UserService depends on EmployeeService , which also depends on UserService . Angular will have to instantiate EmployeeService to create UserService , which depends on UserService , itself.
A cyclic dependency is an indication of a design or modeling problem in your software. Although you can construct your object graph by using property injection, you will ignore the root cause and add another problem: property injection causes Temporal Coupling. Instead, the solution is to look at the design closely.
The best answer is probably to extract your service stuff into a separate project, or at least the service contracts (IMyService
). That should let both of your existing projects reference the service contracts without any conflicts. If you want to add other interfaces or add more implementations of the same interface, this will now be easy too.
An additional benefit may be a better overall architecture: Keeping contracts in a separate project without any actual logic (only interfaces) will generally result in better organized and cleaner code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With