NServiceBus具有自定义ORM的多租户工作单元

时间:2012-12-13 15:57:42

标签: multithreading orm nservicebus multi-tenant unit-of-work

以下是我的参数:

  • 使用默认构建器
  • 的简单NServiceBus Saga实现
  • SQL Server上的内部ORM
  • 多租户 - 我在同一个网站上运行两个ASP.NET MVC 4域,每个域都有自己的数据库

我们使用静态方法配置我们的ORM,如下所示:

public class EndpointConfig: IConfigureThisEndpoint, IWantCustomInitialization {
  public void Init() {
    var bus = Configure.With()
      .AutofacBuilder()
      .UnicastBus().LoadMessageHandlers().DoNotAutoSubscribe()
      .XmlSerializer()
      .MsmqTransport().IsTransactional(true).PurgeOnStartup(false)
      .MsmqSubscriptionStorage()
      .Sagas().RavenSagaPersister().InstallRavenIfNeeded()
      .UseInMemoryTimeoutPersister()
      .CreateBus()
      .Start();

     SlenderConfiguration.Init(bus);
  }
}

public class SlenderCofnigruation {
  private static ORMScope scope { get; set; }

  public static void Init(IBus bus)
  {
    ORMConfig.GetScope = () =>
    {
       var environment = "dev";
       if (bus.CurrentMessageContext.Headers.ContainsKey("Environment"))
         environment = bus.CurrentMessageContext.Headers["Environment"];

       if (scope == null)
         scope = new SlenderScope(ConfigurationManager.ConnectionStrings[environment].ConnectionString);
      return scope;
    };
  }
}

这在我的单租户Beta环境中运行良好 - 可以重新使用该静态范围,因为对于给定的部署,环境标头始终是相同的。

我理解这个不会适用于上述多租户情况,因为NServiceBus将重用消息中的线程。然后将使用相同的范围,如果消息是针对不同的环境,则会导致问题。

我认为我想要的是每个消息的单个范围,但我真的不确定如何到达那里。

我见过Unit Of Work Implementation for RavenDB,以及全双工样本中的工作单元实现,但我不确定这是正确的路径。

我也看过DependencyLifecycle枚举,但我不知道如何根据我必须设置GetScope函数的方式来解决范围。

显然我不知道这里发生了什么。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

如果您需要基于每个消息执行某些操作,请考虑使用消息变更器(IMutateIncomingMessages)以及具有某种线程静态状态的工作单元管理。