1

Ich bin verwirrt über den richtigen Weg, um meine DbContext Lebensdauer mit Dependency-Injektion in meiner WinForms-Anwendung zu verwalten. Gerade jetzt, ich habe Code, der wie folgtDbContext Lifetime mit Dependency Injection

static class Program 
{ 
    // This is the main window's controller, which stores all the 
    // dependencies that are resolved in the composition root and handles 
    // passing those dependencies to other objects 
    private static IMainController mainController; 

    private static void ComposeDependencies 
    { 
     UnityContainer container = new UnityContainer(); 
     container.RegisterType<IMyContext, MyContext>(); 
     container.RegisterType<IOrderRepository, OrderRepository>(); 
     container.RegisterType<IOrderService, OrderService>(); 

     mainController = new MainController(
     container.Resolve<IOrderService>()); 
    } 
} 

public class OrderRepository : IOrderRepository 
{ 
    private readonly IMyContext context; 

    public OrderRepository(IMyContext context) 
    { 
     this.context = context; 
    } 
} 

public class OrderService : IOrderService 
{ 
    private readonly IOrderRepository repository; 

    public OrderService(IOrderRepository repository) 
    { 
     this.repository = repository; 
    } 
} 

public class MainController 
{ 
    private readonly IOrderService orderService; 

    public MainController(IOrderService orderService) 
    { 
     this.orderService = orderService; 
    } 

    public void DoSomethingWithAnOrder() 
    { 
     FirstTypeOfController controller = new FirstTypeOfController(this.orderService); 

     // Show window, assign controller, etc. 
    } 

    public void DoSomethingElseWithAnOrder() 
    { 
     SecondTypeOfController controller = new SecondTypeOfController(this.orderService); 

     // Show window, assign controller, etc. 
    } 
} 

sieht das Problem, das ich habe, ist, dass dieses Muster Ergebnisse in allen meinen Repositories erstellt wurden, wenn mein Programm gestartet wird, so dass die MyContext Instanzen bleiben um durch die ganze Programm. Wenn die Datenbank außerhalb meines Programms aktualisiert wird, sieht mein Programm die neuen Daten daher nicht, da MyContext Verweise auf die Daten verwendet, die es bereits geladen hat.

Wenn dies eine Webanwendung wäre, hätte ich mit jeder Anfrage neue Abhängigkeiten, aber da dies WinForms ist, verstehe ich nicht, wie ich dieses Problem umgehen kann, während ich einen einzigen Kompositionswurzel verwalte und ohne meine Unity-Container rund um mein Programm (oder mit einem statischen Verweis darauf), damit jeder Controller seine eigenen Abhängigkeiten pro Instanz auflösen kann.

Was ist die Standardlösung für dieses Problem, und gibt es etwas, das ich falsch mache mit, wie/wo ich meine Abhängigkeiten komponieren oder meine DbContext?

Ich weiß, dass MVC mehr für Web-Anwendungen gedacht ist und etwas wie MVVM oder MVP ist vielleicht besser für Nicht-Web geeignet, aber diese hätten das gleiche Problem mit einem einzigen Kompositionsstamm, der nur einmal aufgerufen wird.

+0

Haben Sie es geschafft, dieses Problem zu lösen? –

+0

Ich habe eine Lösung gefunden, aber ich bin mir nicht sicher, ob es so gemacht werden sollte. Ich habe eine 'MyContextFactory' erstellt, die ich als Abhängigkeit in alle meine Repositorys injiziere (anstatt' MyContext' zu injizieren), und dann benutze ich diese Factory, um ein neues 'MyContext'-Objekt innerhalb jeder Methode zu erstellen, die diesen Kontext verwendet. Es funktioniert, aber ich bin besorgt, dass es nicht eine empfohlene Art und Weise ist, damit umzugehen. –

Antwort

0

Es hängt davon ab, wie Sie Ihre Abhängigkeitsinjektion konfiguriert haben, ob Singleton oder eine Instanz pro Bereich. Ich weiß, dass auf Ninject DI Framework, um Sie durch die Verwendung angeben:

//Thread Scope (New instance on each injection) 
kernel.Bind<IInterface>.To<ConcreteClass>().InThreadScope(); 


//Singleton Scope (One instance per application) 
kernel.Bind<IInterface>.To<ConcreteClass>().InSingletonScope() 
+0

Da aber alle Abhängigkeiten in meinem Composition Root aufgelöst sind und ich dann Referenzen auf diese Abhängigkeiten in 'MainController' behalte und sie um das Programm herum gebe, werden sie nie wieder aufgelöst. Ich möchte Abhängigkeiten, die pro Instanz Lebensdauern mit jedem neuen Fenster haben, das geöffnet wird, aber ich weiß nicht, wie man das erreicht, ohne meine Abhängigkeiten jedes Mal wieder zu lösen, wenn ein Fenster geöffnet wird, was ich als schlechte Praxis verstehe. Es ist mein Verständnis, dass der Kompositionswurzel nur einmal aufgerufen werden sollte. –

0

ich nicht nichts falsch mit der Implementierung sehen, es richtig aussieht. Das ist richtig, Sie initialisieren Ihre Repositories, wenn Ihr Programm startet, und das ist gut, und Sie behalten Ihre Kontexte für die gesamte Anwendungslebensdauer bei. Mit Repositorys rufen Sie eine Methode auf, die eine Aktion gegen die Datenbank ausführt. Im Falle des Datenabrufs erhalten Sie immer die neuesten Daten, egal was passiert, wenn sie korrekt implementiert werden, es sei denn, Sie würden sie beim Laden der Anwendung abrufen und für zukünftige Zugriffe speichern (wie globale Variablen, Einstellungen als Beispiel).

+0

Das dachte ich auch, aber wenn ich einige Daten über Entity Framework erhalte, aktualisiere Daten über SQL, dann bekomme ich die gleichen Daten wieder über Entity Framework, das zweite Mal, wenn ich Daten durch EF erhalte, hat es immer noch den ursprünglichen Wert. Ich dachte, dass ich etwas falsch mache, aber ich stieß auf diese zweite Antwort in diesem Beitrag, die dieses Verhalten zu bestätigen scheint http://stackoverflow.com/questions/13138243/entity-framework-linq-query-finds-entries-by -original-data-but-returns-referenc –

+0

Auch dieser Beitrag http://stackoverflow.com/questions/28042161/ef-returns-old-values –