当依赖是循环的时候,如何在 Startup.cs 中实现依赖注入?

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

我有一个 MyProject 项目,其中有 IMyService 接口和实现 IMyServiceMyService class。在 Startup.cs class 我依赖注入它们:

// MyProject project | Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IMyService, MyService>();
}

因为 MyService 有很多依赖项(对第 3 方进行许多 REST 调用等)我想为开发环境创建它的存根版本。我创建了新的 MyStubsProject,它引用了 MyProject。我将 IMyService 的存根版本实现到 MyStubsProject:

// MyStubsProject project
public class MyStubService : IMyService
{
    ...
}

所以现在我想将依赖注入添加到 Startup.cs class:

// MyProject project | Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    if (isDevelopmentEnvironment)
        services.AddScoped<IMyService, MyStubService>();
    else
        services.AddScoped<IMyService, MyService>();
}

但是如果我加上那个,MyProjectMyStubsProject.

之间就会有循环依赖

我应该如何在 Startup.cs 中实现对 class MyStubServiceMyStubsProject 项目的引用?

您可以使用预编译器指令 #if 来确定您的项目是设置为调试还是发布。编译器将完成剩下的工作!

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

最好的答案可能是将您的服务内容提取到一个单独的项目中,或者至少是服务合同 (IMyService)。这应该让您现有的两个项目都引用服务合同而不会发生任何冲突。如果您想添加其他接口或添加同一接口的更多实现,现在也很容易。

另一个好处可能是更好的整体架构:在没有任何实际逻辑(仅接口)的情况下将合同保存在单独的项目中通常会产生更好的组织和更清晰的代码。