使用 ASP.Net 核心连接到 2 个不同的 MartenDB 数据存储

Connect to 2 different MartenDB datastores with ASP.Net Core

在 ASP.Net Core 中设置 MartenDB 数据存储时,通常将这样的代码放在 Startup.cs:

services.AddMarten(o =>
{
    o.Connection(configuration.GetConnectionString("MyDatabase"));
    o.AutoCreateSchemaObjects = AutoCreate.All;
    o.Serializer(new JsonNetSerializer { EnumStorage = EnumStorage.AsString });
});

这允许您随后将 IDocumentSession 和 IDocumentStore 注入您的各种 类 以使用该数据库。

现在,如果您必须连接到第二个数据库,您会怎么做?我查看了 ISessionFactory 但显然您无法从此处更改连接字符串。您需要手动创建和注册新的 DocumentStore 吗?

为了回答我自己的问题,我最终为每个我想连接的数据库创建了一个自定义的 DocumentStore 和 ISessionFactory,然后注入了自定义的 SessionFactory。

这是代码(为简洁起见,仅显示每个 class 的一个实例。只需将 Db1 替换为 Db2 每个 class 的第二个版本):

自定义 DocumentStore:

public class Db1Store : DocumentStore
{
    public Db1Store(StoreOptions options) : base(options)
    {
    }
}

自定义SessionFactory:

public class Db1SessionFactory : ISessionFactory
{
    private readonly Db1Store store;

    public Db1SessionFactory(Db1Store store)
    {
        this.store = store;
    }

    public IQuerySession QuerySession()
    {
        return store.QuerySession();
    }

    public IDocumentSession OpenSession()
    {
        return store.OpenSession();
    }
}

服务注册(这取代了 services.AddMarten 调用):

  services.AddSingleton(p =>
  {
      var options = new StoreOptions();
      options.Connection(configuration.GetConnectionString("DB1"));
      options.AutoCreateSchemaObjects = AutoCreate.All;
      options.Serializer(new JsonNetSerializer { EnumStorage = EnumStorage.AsString });
      return new Db1Store(options);
  });
  
  services.AddSingleton<Db1SessionFactory>();

然后将 Db1SessionFactory 实例注入 class,然后 运行 查询如下:

var result = await db1SessionFactory.QuerySession().Query<MyAwesomeTable>().ToListAsync();

缺点

  • 我更愿意注入 QuerySession 或 DocumentSession,但如果不移动到 Autofac 或支持命名实例的类似 DI 容器,我看不出有什么方法可以做到这一点。

  • 我不确定以这种方式创建这些 QuerySession/DocumentSessions 会有什么缺点。这可能是一个糟糕的权衡。