【问题标题】:How to call another project's method where DI is implemented如何在实现DI的地方调用另一个项目的方法
【发布时间】:2020-02-15 16:51:48
【问题描述】:

我认为我实现了一个糟糕的架构。请尝试关注我。

我有 project1 这是一个简单的刮板。每当它收到来自其抓取过程的响应时,它都希望将抓取的数据保存到数据库中。它有自己的 DI 容器。

我有 project2,它负责执行数据库迁移,我还将访问和修改数据库的逻辑放在这里。我只想将管理数据库的所有逻辑保留在一个地方。它有自己的 DI 容器。

最后,我有 project3,它是一个 API,每当被询问时,它都会为存储在数据库中的数据提供服务。它有自己的 DI 容器。

如您所见,project2 位于中间,它既被用于保存数据的爬虫项目使用,也被用于提供数据的 API 项目使用。 在 project2 中,我的 DI 注册如下所示:

private static IServiceCollection ConfigureServices(IConfiguration Configuration)
{
    IServiceCollection services = new ServiceCollection();

    // Inject IOptions<T>
    services.AddOptions();
    var dbSettings = Configuration.GetSection("Settings");
    services.Configure<DbSettings>(dbSettings);

    return services;
}

它所做的是查看 appsettings(只有一个连接字符串指向已保存的数据库)并准备 IOption 在需要的地方注入。 所以在 project2 中有一个例如检查数据库是否为空的方法。

public class DbClient : IDbClient
{
    private readonly IOptions<DbSettings> _dbSettings;
    public DbClient(IOptions<DbSettings> dbSettings)
    {
        _dbSettings = dbSettings;
    }

    public bool IsDbEmpty()
    {
        using (SqlConnection connection = new SqlConnection(_dbSettings.Value.ConnectionString))
        {
            var isEmpty = connection.QueryFirst<string>("SELECT COUNT(1) WHERE EXISTS (SELECT * FROM Test)");
            Console.ReadLine();
        }
    }
}

猜猜问题出在哪里?每当我尝试从 project1(刮板)或 project3(API)调用此方法时,都不会注入 IOptions,因为我没有'不调用 project2 的容器。我该如何解决这个问题?提前致谢!

【问题讨论】:

  • “project2”是否需要它自己的容器?听起来它应该只是一个由 project1 和 project3 使用的类库
  • @devNull 不一定.. 但是如果不使用 IOption(因此是 DI)模式,我该如何将连接字符串传递给方法?

标签: c# .net dependency-injection containers


【解决方案1】:

一种方法是让您的共享项目(“project2”)公开一些可供消费应用程序使用的配置功能(“project1”和“project3”)。

使用 .NET Core,您可以通过在共享项目(“project2”)中定义 IServiceCollection 扩展方法来做到这一点:

public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddProject2(this IServiceCollection services, IConfiguration configuration)
    {
        services.AddOptions();
        var dbSettings = configuration.GetSection("Settings");
        services.Configure<DbSettings>(dbSettings);

        return services;
    }
}

然后从消费项目(“project1”和“project3”)的启动中调用它:

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddProject2(Configuration);

    ...
}

请注意,您可以在任何使用它的项目中定义“project2”所需的配置。

【讨论】:

  • Mmmm 以这种方式还行不通。原因是当您从例如 project1 调用扩展方法时,您将必须通过 IConfiguration .. 和在这种情况下,您传递的 IConfiguration 是 project1 的那些不包含 project2.. 的 appsettings
  • @Tarta 因此我的评论是“请注意,您可以在任何使用它的项目中定义“project2”所需的配置。”
  • 这通常是配置的工作方式。如果这些设置是“可配置的”,那么您可以简单地在 AddProject2 方法中对它们进行硬编码
  • 哦,现在我明白了!但是通过这种方式,我不再保留我试图通过保持角色分离来实现的单一职责。我的意思是我想将与数据库相关的所有内容都保留在 project2.. 这样现在我还必须在其他项目中定义连接字符串
  • @Tarta 可能。尽管该问题也有解决方案,例如creating shared settings
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-18
  • 1970-01-01
  • 1970-01-01
  • 2021-10-18
  • 2021-07-19
  • 1970-01-01
相关资源
最近更新 更多