2016-12-25 1 views
1

Meine App verwendet ein Singleton-Muster für eine Handlerklasseninstanz. Es ist für die Behandlung einiger Ereignisse verantwortlich:Wie aktualisiere ich DB in Singleton-Instanz?

public class MyHandler 
{ 
    public void HandlerEvent(object sender, EventArgs e) 
    { 
     //want to update DB here 
    } 
} 

Es ist möglicherweise MyHandler muss Interaktion mit DB starten. Also kann ich es tun? Es ist meine Vision:

  1. nur zäh befestigen DbContext als Singleton bei MyHandler. Offensichtlich ist es eine schlechte Idee.
  2. Verwenden Sie ASP.Net Core DI-Funktionen und senden Sie DbContext an MyHandler, aber als eine Instanz "eine pro Anforderung". Ich denke, in meinem Fall (MyHandler ist Singleton) ist dies ähnlich zu 1
  3. Do durch using Operator, d.h. als atomare Transaktion, für z.B. using(var context = new XDbContext()) {...} Für mich ist es ein guter Ansatz, aber DbContext der Entity Framework Core-Implementierung benötigt DbContextOptions als Argument des Konstruktors. Wenn ich einen parameterlosen Konstruktor für XDbContext deklariere, löst er eine Ausnahme aus.

Irgendwelche Ideen?

+0

Warum Sie nicht die Instanz in jeder Anforderung verlängern? Wie zum Beispiel eine 'DbContext'-Eigenschaft in Ihrer' MyHandler'-Klasse und in der Sie Ihre Instanz von 'XDbContext' erneuern, brauchen Sie sich keine Gedanken um vorherige Instanzen zu machen, da diese über GC gesammelt werden. – Emad

+0

@Emad in meinem Fall 'HandlerEvent' verarbeitet Nachrichten, die von azure Service Bus ankommt, d. H. Es hängt nicht von http-Anfragen ab – Mergasov

+0

Mein Punkt ist immer noch gültig, obwohl die Antwort von Egorikas dasselbe mit dem Fabrikmuster tut. Sie können den gesamten Code der Factory in der get-Methode meiner DbContext-Eigenschaft erstellen lassen. – Emad

Antwort

1

Ich habe ein ef Kern-Tutorial (https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext) gesehen und wie ich verstanden habe, DbContextOptions - ist nur ein Objekt mit Konfigurationsparameter drin. Wenn ich das gleiche Problem hätte, würde ich den dritten Weg (mit der Verwendung) verwenden, würde aber einen Helfer für das Injizieren von Parametern oder das Verwenden einer Fabrik dafür schaffen. Ich fand ein Beispiel Fabrik im Tutorial

using Microsoft.EntityFrameworkCore; 
using Microsoft.EntityFrameworkCore.Infrastructure; 

namespace MyProject 
{ 
    public class BloggingContextFactory : IDbContextFactory<BloggingContext> 
    { 
     public BloggingContext Create() 
     { 
      var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>(); 
      optionsBuilder.UseSqlite("Filename=./blog.db"); 

      return new BloggingContext(optionsBuilder.Options); 
     } 
    } 
} 

Beispiel für die Verwendung:

public class MyHandler 
{ 
    public void HandlerEvent(object sender, EventArgs e) 
    { 
     // Or make 'Create' method static 
     using(var context = new BloggingContextFactory().Create()) 
     { 
       . . . 
     } 
    } 
} 
+0

Kann ein solcher Ansatz die Haupt-DB-Konfigurationen untergraben, die in der OnModelCreating-Methode implementiert wurden? Oder ist dieser Konstruktor für OnModelCreating-configs nicht wichtig? – Mergasov

+0

@Mergasov Wie ich weiß, wird neuer EF-Kern in der Art wie ASP.NET-Kern geschrieben. Das bedeutet, dass wir web.config nicht haben und unsere Eigenschaften in einer anderen Datei speichern (appsettings.json zum Beispiel), also nehme ich an, dass dieser Ansatz Haupt-DB-Konfigurationen untergraben kann, aber ich bin mir nicht sicher. Watch https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-strings und ASP.NET Core-Abschnitt – Egorikas