0

Ich habe eine Anwendung, die an 2 verschiedenen Standorten verwendet wird. Jede Site hat ihre eigene Datenbank.Einen DbContext in die Verwendung von Ninject Dependency-Injektion pro Benutzersitzung wechseln

Es gibt 2 DbContexte, 1 für jede Site. Wenn der Benutzer meine Anwendung öffnet, gibt es eine Begrüßungsseite, auf der sie ihre Website auswählen. Nach der Auswahl der Site wird der Kernel neu gebootet, um den DbContext für die ausgewählte Site zu verwenden.

private void RebindDbContext(string site) 
{ 
    switch (site) 
    { 
     case "Site1": 
      _kernel.Rebind<DbContext>().To<DbContext1>().InRequestScope(); 
      break; 
     case "Site2": 
      _kernel.Rebind<DbContext>().To<DbContext2>().InRequestScope(); 
      break; 
    } 
} 

Jetzt für die Bob & Mary Erklärung: Dies funktioniert gut, wenn Bob Website wählt 1. Aber wenn Mary eine Website 2. Die DbContext für Bob wählt erneut gebunden Website 2. Was ich will, ist für Bob und Mary in der Lage, die Anwendung gleichzeitig zu verwenden, ohne sich gegenseitig zu beeinflussen.

Ich habe versucht mit TransientScope, ThreadScope und InRequest Scope, aber keiner von diesen hat funktioniert.

Die Anwendung auf einem IIS-Server wird pro Anwendung für jede Hilfe

+1

Wie wäre es mit dem Einsatz von Ninject Provider für diesen Zweck? Oder binden Sie an Methode statt an Rebind. – MaKCbIMKo

Antwort

2

Bindungen sollen getan werden einmal

Dank laufen, nicht auf zustandsabhängig. In diesem Fall haben Sie ein paar Optionen:

1) Ein Ninject.Activation.IProvider

public class DbContextProvider : Ninject.Activation.IProvider 
{ 
    public Type Type 
    { 
     get { return typeof(DbContext); } 
    } 

    public object Create(IContext context) 
    { 
     var siteProvider = context.Kernel.Get<ISiteProvider>(); // use a provider to find which site is being used 
     switch (siteProvider.Current) 
     { 
      case "Site1": 
       return new DbContext1(); // or use a factory to create 
      case "Site2": 
       return new DbContext2(); 
     } 
    } 
} 

dann:

Bind<DbContext>().ToProvider<DbContextProvider>().InRequestScope(); 

2) Bedingte Bindung

Der When() Modifikator eine Reihe von Überladungen für verschiedene Zustände, oder Sie könnten c Erweitern Sie eine Erweiterungsmethode, wenn Sie einen Typ verwenden, den Sie häufig verwenden.

 Bind<DbContext>().To<DbContext1>() 
      .When(request => request.ParentContext.Kernel.Get<ISiteProvider>().Current == "Site1") 
      .InRequestScope(); 

     Bind<DbContext>().To<DbContext2>() 
      .When(request => request.ParentContext.Kernel.Get<ISiteProvider>().Current == "Site2") 
      .InRequestScope(); 

Dies ist eine gute Option, wenn Sie nur wenige Bedingungen haben, dass diese Bindung angewendet werden kann. Wenn Ihre Logik komplexer wird, suchen Sie den Anbieter. Beachten Sie außerdem, dass bedingte Bindungen eine Leistungseinbuße verursachen.

3) Eine ToMethod() Bindung

Für die einfachste Bindung Logik, können Sie haben Ninject einige Code jedes Mal laufen die Bindung gelöst ist:

Bind<DbContext>().ToMethod(context => 
      context.Kernel.Get<ISiteProvider>().GetSite()); 

Grundsätzlich, die Option, die Sie wählen, hängt von Wie viel Logik ist beteiligt, um zu entscheiden, welche Instanz aktiviert werden soll. In jedem Fall können Sie entweder new() eine Instanz, oder Sie haben Zugriff auf die iKernel in dem Sie eine Instanz auflösen kann:

context.Kernel.Get<DbContext2>(); 

hier einige offizielle Dokumentation des Aktivierungsprozesses:

https://github.com/ninject/Ninject/wiki/Providers%2C-Factory-Methods-and-the-Activation-Context

+0

Option 1 funktionierte –