当前位置: 首页 > 知识库问答 >
问题:

ASP.NET核心DI公司上下文提供程序?[副本]

虞裕
2023-03-14

我正在用ASP.NET Core3实现webapi。

在后端,我们有许多公司数据库,它们具有完全相同的模式/表等。

我正在尝试实现一个公司数据库上下文提供程序,它将让我在运行时解析正确的公司数据库上下文。

在my Startup.cs中,我有以下代码,可以让您了解我要做的事情:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<CompanyDbContext>(opt => opt.UseSqlServer(Configuration.GetConnectionString("CompanyDbConnection")));

    services.AddScoped<ICompanyRepository, CompanyRepository>();

    services.AddDbContext<System.Func<CompanyType, ICompanyDbContext>>(dbContextOptionsBuilder => key =>
    {
        switch (key)
        {
            case CompanyType.HKG:
                return dbContextOptionsBuilder.UseSqlServer(Configuration.GetConnectionString("HkgCompanyDbConnection"));
            case CompanyType.SHG:
                return dbContextOptionsBuilder.UseSqlServer(Configuration.GetConnectionString("ShgCompanyDbConnection"));
            default:
                throw new KeyNotFoundException();
        }
    });

    //...

与只有1个连接的通用CompanyContext不同,我希望将类似服务提供程序的东西注入CompanyRepository构造函数中,该构造函数将允许我在存储库函数中(通过传递参数)解析不同情况下的不同公司DBContext。

其思想是代码的最后一部分应该根据提供的键返回正确的上下文。但显然最后一部分不起作用。如果不明显,repository类将保存从数据库返回数据的所有函数。

一个人该怎么做呢?

共有2个答案

宗项禹
2023-03-14

下面的评论这是如何你可以做它,通过检查什么是公司Id或名称上的请求,我有一个怀疑这是你最终需要的。

哦,是的,我忘了,这段代码是在。NET Core2.2上测试过的,但它应该会带来不同。

    services.AddScoped<ICompanyType, CompanyType>();
    services.AddEntityFrameworkSqlServer();
    services.AddDbContext<CompanyDbContext>((serviceProvider, options) =>
        {
            var companyCode = serviceProvider.GetRequiredService<ICompanyType>().Get();
            string connectionString = string.Empty;
            switch (companyCode)
            {
                case CompanyType.HKG:
                    connectionString = Configuration.GetConnectionString("HkgCompanyDbConnection");
                    break;
                case CompanyType.SHG:
                    connectionString = Configuration.GetConnectionString("ShgCompanyDbConnection");
                    break;
                default:
                    throw new InvalidOperationException();
            }
            options
                .UseSqlServer(connectionString)
                .UseInternalServiceProvider(serviceProvider);
        });

和一些虚拟公司类型实现:

public class CompanyType: ICompanyType
{
    public const string HKG = "HKG";
    public const string SHG = "SHG";
    public string Get()
    {
        Random rand = new Random((int) DateTime.UtcNow.Ticks & 0x0000FFFF);
        var flipCoin = rand.Next(0, 1);
        return flipCoin == 0 ? HKG : SHG;
    }
}

public interface ICompanyType
{
    // dummy code, to be replaced with what is needed
    string Get();
}
羊新翰
2023-03-14

我最近做了一些相当类似的事情(但不完全是),并且遇到了这个很好的答案,我认为它正好满足了你的需求。

基本步骤:

共享委托

public delegate IService ServiceResolver(CompanyType key);

添加要解析的实例

//Note: Default Service Lifetime for AddDbContext is Scoped - perfect!
services.AddDbContext<HkgCompanyContext>(options...);
services.AddDbContext<ShgCompanyContext>(options...);

解析程序服务

services.AddScoped<ServiceResolver>(serviceProvider => key =>
{
   switch (key)
   {
      case CompanyType.HKG:
         return serviceProvider.GetService(HkgCompanyContext);
      case CompanyType.SHG:
         return serviceProvider.GetService(ShgCompanyContext);
      default:
         throw new KeyNotFoundException();
   }
}
 类似资料:
  • .NET核心和ASP.NET核心到底有什么区别?

  • 我有一个由后台服务持续写入的日志文件。到目前为止,用户需要能够下载该文件。当我返回 MVC 时,由于内容长度不匹配,我得到一个 InvalidOperationException,大概是因为在提供文件时某些内容已写入文件。有一个文件已提供,它基本上没问题,但它通常有一个不完整的最后一行。 后台服务本质上是这样做的: 以下是控制器动作的一些变化(都有相同的结果): 这是我尝试上述任一方法时遇到的异常

  • 我需要在单个C # ASP.NET核心应用程序上提供多个swagger UIs。这是必要的,因为应用程序API由用于UI和其他内容的内部“私有”API和可以被其他应用程序和用户访问的“公共”API组成。 每个Swaggerendpoint都应该在自己的Swagger UI页面上,并具有不同的URL地址。我能够在<code>启动时使用此代码将现有API规范划分为两个不同的json文件,并将json文

  • 在R2DBC入门视频之后,我将一些存储库转换为以PostgreSQL作为数据库的现有Spring Boot应用程序中的反应式。该应用程序在转换前工作。在我尝试启动应用程序后,我得到以下错误: QueryMethod odEvalue ationContextProvider类应该在那里。我猜数据库配置不能与现有数据库和Spring Data配置共存。 Spring Boot版本为2.0.5。发布。

  • 我正在开发一个利用和的项目。为了在我的程序中使用顶点和片段着色器,我需要使用的最小OpenGL版本是。我检查了OpenGL版本和GLSL版本,结果如下: 我在Linux操作系统上使用Eclipse作为我的C++开发IDE(我使用的这个特定的disdo是PCLinuxOS)。

  • 我正在使用ASP.NET内核。我正在创建一个基本的WebAPI。我想在出现问题时显示一个JSON错误。 打印屏幕在我的屏幕上显示want I want。唯一的问题是它的发送状态码为200。 我可以通过这样做来解决问题: 真诚的,布莱希特

  • 出身背景 我们正在开发一个出售给其他公司的网络商店。这些公司托管网络商店,并在自己的服务器上销售产品。网店使用Paypal Rest API为客户付款。https://developer.paypal.com/docs/api/ 为了将Paypal激活为一种支付方式,各公司在webshop管理区提供其Paypal详细信息。 我们现在怎么做 现在,这些公司需要创建一个贝宝开发者账户,然后在devel

  • 我已将 Cosmos DB 集成到我的 ASP.NET 核心 API 项目中,使用 Cosmos DB 提供程序附带的最新 EF 核心包。 当在本地ASF集群中运行时,我能够成功地使用这个提供者,连接到本地Cosmos DB模拟器实例。然而,当试图在本地ASF或Azure托管的ASF中运行时,我无法连接到Azure Cosmos DB实例。由于某种原因,在初始化数据库/集合的种子时,我一直收到40