【问题标题】:How to get ConnectionString from appsettings.json into DA project?如何从 appsettings.json 获取 ConnectionString 到 DA 项目中?
【发布时间】:2021-08-31 11:22:05
【问题描述】:

到目前为止,我使用 EFCore (3.1) 开发了多个 ASP.NET Core Web 应用程序,其中我在同一个项目中拥有所有层(模型、数据访问、业务逻辑...)。为了向 DbContext 提供数据库连接字符串,我使用了 DependencyInjection 并在 ConfigureServices 方法中调用了 AddDbContext,如下所示:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<DbContextName>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    // ...
}

然后,我通过每个控制器类中的构造函数获取上下文的实例,并使用它与数据库进行交互。连接字符串始终存储在 Web 应用程序的 appsettings.json 文件中。

现在我正在开发一个基于 EF 5 的更复杂的应用程序,该应用程序包含每个层的单独项目,包括一个用于 DataAccess 层的项目。为了避免为解决方案中的每个项目带来无数的单独配置文件,我仍然想将数据库连接字符串存储在 appsettings.json 文件中。

如何将 appsettings.json 文件中的连接字符串提供给 DataAccess 项目中的 DbContext?由于我无法访问 DataAccess 项目中 OnConfiguring 方法中的配置,因此我无法以这种方式提供它。是否仍然可以像以前一样通过AddDbContext 执行此操作,或者通常如何执行此操作?到目前为止,我能找到的所有示例都适用于硬编码的连接字符串,因此从未在其中任何一个中解释过。

【问题讨论】:

    标签: c# asp.net-core entity-framework-5


    【解决方案1】:

    1.可以通过创建单例服务提供连接字符串来解决:

    在共享项目中定义IConnectionStringProvider 接口。

    public interface IConnectionStringProvider
    {
       public string DefaultConnectionString {get;}
    }
    

    在您的 Web 项目中,您将实现提供连接字符串的服务。

    public sealed class ConnectionStringProvider : IConnectionStringProvider
    {
       private readonly IConfiguration _configuration;
       public ConnectionStringProvider(IConfiguration configuration)
       {
          _configuration = configuration;
       }
    
       public string DefaultConnectionString => _configuration.GetConnectionString("DefaultConnection");
    }
    

    服务注册:

    public class Startup
    {
       // ...
       public void ConfigureServices(IServiceCollection services)
       {
          services.AddSingleton<IConnectionStringProvider,ConnectionStringProvider>();
          // ...
       }
       // ...
    }
    

    最后你可以在你的 DAL 项目中注入IConnectionStringProvider,检查下面的例子(假设你的类名是DAL)。

    public class DAL
    {
       // ...
       private readonly IConnectionStringProvider _connectionStringProvider;
       
       public DAL(IConnectionStringProvider connectionStringProvider)
       {
          _connectionStringProvider = connectionStringProvider;
       }
       
       public void ConfigureServices(IServiceCollection services)
       {
          services.AddDbContext<DbContextName>(options => options.UseSqlServer(_connectionStringProvider.DefaultConnectionString));
          // ...
       }
       // ...
    }
    

    重要提示:DAL 类应注册为服务。

    2. 另一种方法是创建一个扩展方法来注册您的 DAL 服务并将IConfiguration 接口作为参数传递。比如:

    public static class DALServices
    {
       public static IServiceCollection AddDALServices(this IServiceCollection services, IConfiguration configuration)
       {
          services.AddDbContext<DbContextName>(options => options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")));
          // ...
          return services;
       }
    }
    

    PS:您需要在 DAL 项目中安装 Nuget 包:Microsoft.Extensions.Configuration

    Starup类调用扩展方法:

    public class Startup
    {
       // ...
       public void ConfigureServices(IServiceCollection services)
       {
          services.AddDALServices(IConfiguration);
          // ...
       }
       // ...
    }
    

    【讨论】:

    • 目前DataAccess项目还是空的,因为开发还处于非常早期的阶段。因此,我在 DAL 项目中没有“DAL”类。除了注入连接字符串之外,这个类还有其他用途吗,还是只为此目的创建它就可以了?
    • 不幸的是,我无法让您的解决方案发挥作用。在这两种情况下,我都会收到错误“System.InvalidOperationException:'没有为此 DbContext 配置数据库提供程序。”。我怀疑发生这种情况是因为我在我的 DataAccess 项目中创建上下文的实例,而不是通过依赖注入。你的解决方案在这种情况下是否有效?如果是,我做错了什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-29
    • 1970-01-01
    • 2017-10-01
    • 1970-01-01
    相关资源
    最近更新 更多