2017-06-05 2 views
0

J'ai parcouru la documentation NServiceBus et j'ai exécuté l'exemple de configuration de plusieurs locataires pour conserver les données saga dans des bases de données individuelles pour chaque client hébergé.Impossible de configurer l'exemple de saga multi-locataires NServiceBus v5 en tant que service hébergé

https://docs.particular.net/samples/outbox/multi-tenant/?version=core_5

J'ai actuellement une application NServiceBus utilisant le package NServiceBus.Host et est en cours d'exécution en tant que service Windows. Il partage une seule table de données saga entre plusieurs locataires, pensant qu'il serait simple de convertir l'échantillon à héberger afin que je puisse voir comment je dois procéder pour convertir mon projet existant en connexions SQL multi-locataires. Cependant, l'exemple utilise une application console et un bus créé manuellement.

Si j'ajoute le package NServiceBus.Host NuGet à l'exemple d'application d'un fichier de EndpointConfig.cs est ajouté comme je le pense, mais je ne peux pas comprendre comment travailler avec le pipeline Executor.

Dans le projet récepteur dans Program.cs il y a ceci:

internal static PipelineExecutor PipelineExecutor; 

var busConfiguration = new BusConfiguration(); 
PipelineExecutor = ((UnicastBus) startableBus).Builder.Build<PipelineExecutor>(); 

Cependant, vous pouvez évidemment pas faire l'intérieur EnpointConfig.cs d'une application hébergée.

Suivant si vous voir MultiTenantOpenSqlConnectionBehavior.cs dans la méthode Invoke vous avez accès au contexte IncomingContext context où les connexions clientes individuelles sont bourrés dans le contexte avec leurs touches correspondantes et la prochaine étape de pipeline est exécutée par next();

class MultiTenantOpenSqlConnectionBehavior : 
    IBehavior<IncomingContext> 
{ 

    public void Invoke(IncomingContext context, Action next) 
    { 
     var defaultConnectionString = ConfigurationManager.ConnectionStrings["NServiceBus/Persistence"] 
      .ConnectionString; 
     #region OpenTenantDatabaseConnection 

     string tenant; 
     if (!context.PhysicalMessage.Headers.TryGetValue("TenantId", out tenant)) 
     { 
      throw new InvalidOperationException("No tenant id"); 
     } 
     var connectionString = ConfigurationManager.ConnectionStrings[tenant] 
      .ConnectionString; 
     var lazyConnection = new Lazy<IDbConnection>(() => 
     { 
      var connection = new SqlConnection(connectionString); 
      connection.Open(); 
      return connection; 
     }); 
     var key = $"LazySqlConnection-{defaultConnectionString}"; 
     context.Set(key, lazyConnection); 
     try 
     { 
      next(); 
     } 
     finally 
     { 
      if (lazyConnection.IsValueCreated) 
      { 
       lazyConnection.Value.Dispose(); 
      } 
      context.Remove(key); 
     } 

     #endregion 
    } 
} 

Puis, en MultiTenantConnectionProvider.cs, le PipelineExecutor statique mentionnées ci-dessus est référencé et que contexte la connexion peut être récupérée avec la même clé qui a été définie dans la classe ci-dessus.

class MultiTenantConnectionProvider : 
    DriverConnectionProvider 
{ 

    public override IDbConnection GetConnection() 
    { 
     var defaultConnectionString = ConfigurationManager.ConnectionStrings["NServiceBus/Persistence"] 
      .ConnectionString; 

     #region GetConnectionFromContext 

     Lazy<IDbConnection> lazy; 

     // 
     // This line is the problem. The static Program.PipelineExecutor is accessed 
     // 
     var pipelineExecutor = Program.PipelineExecutor; 

     var key = $"LazySqlConnection-{defaultConnectionString}"; 
     if (
      pipelineExecutor != null && 
      pipelineExecutor.CurrentContext.TryGet(key, out lazy)) 
     { 
      var connection = Driver.CreateConnection(); 
      connection.ConnectionString = lazy.Value.ConnectionString; 
      connection.Open(); 
      return connection; 
     } 
     return base.GetConnection(); 

     #endregion 
    } 
} 

Il doit sûrement y avoir un moyen de le faire dans une application hébergée, mais je ne peux trouver aucune information sur la façon de le faire.

+0

Vous cherchez à faire sur la version 5.x NServiceBus? –

+0

Oui, version 5.x. –

Répondre

0

Malheureusement, l'hôte NServiceBus ne prend pas en charge les scénarios de multi-clients. Au lieu de cela, vous pouvez prendre cet échantillon utiliser un self-service hébergé https://docs.particular.net/nservicebus/hosting/windows-service

Le code est assez trivial

+0

C'est une possibilité mais il y a aussi un autre problème que j'ai avec l'exemple de code qui pourrait être un non-go. Je m'interroge sur la sécurité des threads de Program.PipelineExecutor statique. –