9
votes

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?

2

2 Answers

7
votes

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.

1
votes

You can use the precompiler directive #if to determine if your project is set to debug or release. The compiler will do the rest!

// MyProject project | Startup.cs
public void ConfigureServices(IServiceCollection services)
{
#IF DEBUG
        services.AddScoped<IMyService, MyStubService>();
#ELSE
        services.AddScoped<IMyService, MyService>();
#ENDIF
}