Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement dependency injection in Startup.cs when dependencies are circular?

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?

like image 208
Lassi Autio Avatar asked Dec 14 '18 13:12

Lassi Autio


People also ask

How do I get around circular dependency?

Circular dependencies can be introduced when implementing callback functionality. This can be avoided by applying design patterns like the observer pattern.

How do I fix circular dependency error?

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.

What is circular dependency in dependency injection?

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.

What is cyclic dependency and how do you resolve it?

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.


1 Answers

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.

like image 86
Kjartan Avatar answered Oct 26 '22 07:10

Kjartan