【问题标题】:.Net Core 3-tier architecture passing connection string from presentation layer to data layer issue.Net Core 3 层架构将连接字符串从表示层传递到数据层问题
【发布时间】:2019-03-07 23:16:37
【问题描述】:

我有一个 3 层架构的 Web API,如下所示:

PresentationLayer(在表示层我有 appsetting.json 连接字符串所在的位置)

BusinessLayer(类库)

DataLayer(类库)

当我还在使用 .Net Framework 时,我曾经在 dataLayer 中执行以下链接中显示的代码,以从表示层的 web.config 中获取连接字符串:

现在我正在尝试使用 .Net Core 2.1,并且我在数据层中构建了相同的类,但它无法正常工作。如何以最有效的方式将连接字符串从表示层传递到数据层。当我使用 .Net 框架时,是否有类似的方式来传递连接字符串。

你能帮帮我吗?

【问题讨论】:

  • 请不要发布您的代码截图,而是将您的源代码复制/粘贴为文本。
  • 我不认为将连接字符串从 PL 传递到 DL 是否是一个好习惯。
  • 你没有使用实体框架吗?如果没有,我建议你看看它。至少,去了解一下依赖注入。
  • @DavidG 不,我不想使用实体框架。通过依赖注入,您的意思是在数据层中创建一个 appsettings.json?
  • 如果我不得不重新直接使用 ADO.Net,我会伤害到别人。实际上几乎没有必要避免使用它(或另一个 ORM)。无论如何......不,那根本不是 DI,你绝对需要去做你的研究。

标签: c# .net-core asp.net-core-2.0 asp.net-core-webapi 3-tier


【解决方案1】:

有(最少)3 个选项。我认为最好的方法是使用 IoC 容器。也许您更喜欢将 appconfig 文件添加到 DB 层并访问它以进行特定于层的设置。或者,您可以使用默认的注入机制将IConfiguration传递给业务层,然后通过ctors将其传递给DataLayer。

例如

/* ----- Startup.cs ----- */
public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IxxxService, xxxBusinessService>();
}

/* ----- UI Layer ----- */
public xxxController(IxxxService xxxBusinessService)
{
   this.xxxBusinessService = xxxBusinessService;
}

/* ----- BUSINESS LAYER ----- */
/*
UI/controller knows Business service and IConfiguration objects, and default 
injector automatically creates/passes configuration object via ctor to Business layer.
*/
public xxxService(IConfiguration configuration)
{
    this.xxxRepository = new xxxRepository(configuration);
}

/* ----- DATA LAYER ----- */
public class xxxRepository: BaseRepository, IxxxRepository
{
    public xxxRepository(IConfiguration configuration)
        : base(configuration)
    {

    }
}       

public class BaseRepository{

    protected xxxDbContext context;

    public BaseRepository(IConfiguration configuration)
    {   
        var optionsBuilder = new DbContextOptionsBuilder<xxxDbContext>();

        optionsBuilder.UseSqlServer(configuration.GetSection("ConnectionString")["DefaultConnection"]);

        this.context = new xxxDbContext(optionsBuilder.Options);
    }
}

【讨论】:

    【解决方案2】:

    当您有多个层时,您很可能正在使用一个 IOC 容器。在您的数据层中创建一个接口并在您的视图层中执行实现,然后使用您的 IOC 容器注册并获取它。如果不能直接在 SqlConnection 中传递,这是最干净的方法。

    【讨论】:

      【解决方案3】:

      创建 AppSettings 类

      public static class AppSettings
      {
          public static string ConnectionString { get; set; }
      }
      

      在 Startup.cs 中

      public Startup(IConfiguration configuration)
      {
          Configuration = configuration;
          BuildAppSettingsProvider();
      }
      
      public IConfiguration Configuration { get; }
      
      private void BuildAppSettingsProvider()
      {
          AppSettings.ConnectionString = Configuration["ConnectionString"];
      }
      

      现在您可以在表示层中访问 AppSettings。

      100% 有效。

      【讨论】:

        【解决方案4】:

        如何将连接字符串从表示层传递到数据层最有效的方式。当我使用 .Net 框架时,是否有类似的方式来传递连接字符串。

        在 Asp.Net Core 中,通过依赖注入将连接传递给DbConnection 要容易得多。

        • DbConnection改为接受connection string

          public class DbConnection
          {
          public DbConnection(string connectionString)
          {
              _sqlConnection = new SqlConnection(connectionString);
          }
          
        • PresentationLayer注册DbConnection

          services.AddTransient<DbConnection>(serviceProvider => new DbConnection(Configuration.GetConnectionString("DefaultConnection")));
          

        【讨论】:

        • DbConnection 类在类库dataLayer 中。表示层现在与 dataLayer 无关
        • @Whiplash 在 .Net Core 中的引用是可传递的,这意味着如果 ProjectA 引用了 ProjectBProjectB 引用 ProjectC,那么 ProjectA 将能够看到其中的所有内容ProjectC.
        猜你喜欢
        • 2012-03-12
        • 1970-01-01
        • 2011-07-30
        • 2022-01-14
        • 2013-09-27
        • 1970-01-01
        • 2011-09-30
        • 1970-01-01
        相关资源
        最近更新 更多