2016-04-23 7 views
1

Wir haben ein grundlegendes Problem mit der Bereichsdefinition mit Autofac. In unserem Szenario haben wir einige Repositories, die im Singleton-Bereich liegen. Diese Repositories werden mit einem IDbContextProvider (der auch ein Singleton-Bereich ist) injiziert. Der IDbContextProvider ist nur ein Wrapper um einen injizierten Autofac IComponentContext. Wenn ein DbContext benötigt wird, wird er vom DBContextProvider vom Repository angefordert. DbContext ist auf "lifetimescope" beschränkt, grundsätzlich pro Anfrage, da es sich um eine Web API handelt.Autofac Scoping, wenn das Singleton-Scoped-Objekt von ComponentContext aufgelöst wird

Also die Idee ist, dass die Repositories Singleton-Bereich sein können, da es nicht so viele von ihnen gibt und das Scoping des DBContext von Autofac als "pro Anfrage" verwaltet wird. Dies setzt voraus, dass der Autofac ComponentContext den aktuellen "Blatt" -Kontext versteht und den richtigen DbContext zurückgibt. Ein Mitarbeiter, der diese Strategie vorgeschlagen hat, hat mir gesagt, dass dies das Verhalten von StructurMap ist (offensichtlich ein anderes Produkt). Für mich ist es sinnvoll, dass Autofac den aktuellen "Blatt" -Kontext auflöst und den richtigen DbContext zurückgibt, aber wir sehen Parallelitätsprobleme mit dem DbContext, was zu dem Schluss führt, dass der IComponentContext an den Singleton angeheftet ist, der ihn besitzt daher die gleiche DbContext-Instanz zurückgeben.

//This is singleton scoped 
public class DbContextProvider : IDbContextProvider 
{ 

    private readonly IComponentContext _componentContext; 

    public DbContextProvider(IComponentContext componentContext) 
    { 
     _componentContext = componentContext; 
    } 

    public TDbContext GetDbContext<TDbContext>() where TDbContext : IDbContext 
    { 
     //DbContext is scoped PerLifetimeScope but the component context 
     //appears to only understand the context of the singleton that owns 
     //it and returns the same instance no matter the overall context 
     //under which is is requested. 
     return _componentContext.Resolve<TDbContext>(); 
    } 

} 

Gibt es eine Möglichkeit zu erreichen, was wir für hier gehen oder ist die einzige Vorgehensweise zu Umfang des gesamte Abhängigkeitsbaum als PerLifetimeScope das richtige Verhalten zu erhalten.

Dank ...

Antwort

0

IComponentContext resolve mit naher stehenden Lebenszeit, aber miteinander verbundener Lebensdauer ist hier Singleton, so wird es in Behältern gelöst werden. Sie sollten DependencyResolver.Current.GetService

public class DbContextProvider : IDbContextProvider 
{ 


    public DbContextProvider() 
    { 

    } 

    public TDbContext GetDbContext<TDbContext>() where TDbContext : IDbContext 
    { 
     //DbContext is scoped PerLifetimeScope but the component context 
     //appears to only understand the context of the singleton that owns 
     //it and returns the same instance no matter the overall context 
     //under which is is requested. 
     return DependencyResolver.Current.GetService.Resolve<TDbContext>(); 
    } 

} 

verwenden Sie können diese article auch prüfen.

+0

Kommt es nicht darauf an, einen HTTP-Kontext verfügbar zu haben? Diese Funktionalität wird zwischen Web-API- und Nicht-Web-Event-Handlern wiederverwendet, so dass es nicht funktioniert, von etwas abhängig zu sein, das HttpContext benötigt. – swannee

+0

Hımm in Web-Api aktuelle Lebensdauer ist HTTP-Anfrage. Aber erstellen Sie im Nicht-Web Leben, bevor Sie oben auflösen? Wenn Sie erstellen, werde ich meine Antwort testen und bearbeiten, um mit beiden zu arbeiten. Wenn Sie keine neue Lebenszeit starten und direkt aus dem Container auflösen, können Sie das nicht realisieren. –