Autofac - Antrag lifetime-Bereich kann nicht erstellt werden, weil die HttpContext-nicht verfügbar - aufgrund der asynchronen code?
Kurze Frage: So wie diese unbeantwortet problem
Lange Frage:
Ich nur portiert, einige code über von einem MVC 4 + Web-Api-Lösung, mit Autofac in meine neue Lösung, die auch mit Autofac aber nur mit der Web-Api-2 - (kein MVC 5.1 Projekt, nur ein web-api).
In meinem vorherigen Lösung hatte ich MVC4-und Web-Api, also ich hatte 2 Bootstrapper.cs-Dateien, eine für jeden. Kopiert habe ich nur über die Web-Api-bootstrapper für das neue Projekt.
Nun habe ich 2 andere Projekte in die neue Lösung müssen, ziehen Sie ein Abhängigkeit. Können nur davon ausgehen, ich habe mit DependencyResolver.Current.GetService<T>()
obwohl es ein anti-pattern.
Zunächst war dies nicht funktioniert, bis ich die MVC, Dependency Resolver zu den gleichen container:
GlobalConfiguration.Configuration.DependencyResolver =
new AutofacWebApiDependencyResolver(container);
//I had to pull in Autofac.Mvc and Mvc 5.1 integration but this line fixed it
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
Das seltsame ist, zu tun, die nur fixiert es in EINEM dieser Projekte! Hier ist die situation:
Solution.Web project
Bootstrapper.cs that registers both dependency resolvers for web api and mvc.
Solution.ClassLib project
var userRepo = DependencyResolver.Current.GetService<IUserRepo>(); //Good! :)
Solution.WindowsWorkflow project
var userRepo = DependencyResolver.Current.GetService<IUserRepo>(); //Throws exception :(
Ausnahme ist:
Die Anfrage lifetime-Bereich kann nicht erstellt werden, da der HttpContext ist nicht verfügbar.
Nun, bevor wir anfangen, die Schuld des workflow, weiß nur, ich hatte genau dieses set-up funktioniert ganz gut in einer anderen Lösung den workflow in der Lage war, zu verwenden DependencyResolver gut. Also ich vermute, das hatte damit zu tun, mit einer neueren version von Autofac und die Tatsache, dass der workflow läuft asynchron (genau wie die Frage, die ich verknüpft über async-code)
Versuchte ich Wechsel alle Registrierungs-code zu verwenden InstancePerLifetimeScope()
statt InstancePerHttpRequest()
und versuchen, erstellen Sie einen Rahmen:
using (var c= AutofacDependencyResolver.Current
.ApplicationContainer.BeginLifetimeScope("AutofacWebRequest"))
{
var userRepo = DependencyResolver.Current.GetServices<IUserRepo>();
}
Aber es nicht ändern die Ausnahme. Brechen Sie den code unten sogar noch weiter, hier wird die genaue Täter:
var adr = AutofacDependencyResolver.Current; //Throws that exception
Wirklich brauchen, um daran vorbei, zu viel Zeit stecken. Belohnen vorhandenen Antwort mit bounty in 2 Tagen
IUserRepo
direkt aus dem container, ohne .Current
? Auch InstancePerLifetimeScope()
ist besser als InstancePerHttpRequest
.InformationsquelleAutor parliament | 2014-02-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
UPDATE Nov. 20, 2014: In Versionen von
Autofac.Mvc5
da diese Frage veröffentlicht wurde, war die Umsetzung derAutofacDependencyResolver.Current
wurde aktualisiert, um entfernen Sie die Notwendigkeit für eineHttpContext
. Wenn Sie dieses problem Auftritt, und fand diese Antwort, Sie können möglicherweise einfach lösen sich die Dinge durch ein Update auf eine neuere version vonAutofac.Mvc5
. Jedoch, ich lasse die original-Antwort intakt, für Leute zu verstehen, warum die ursprüngliche Frage asker Probleme.Originalantwort:
AutofacDependencyResolver.Current
erfordert eineHttpContext
.Fuß durch den code
AutofacDependencyResolver.Current
sieht wie folgt aus:Und, natürlich, wenn die aktuelle dependency resolver ist eine
AutofacDependencyResolver
dann es geht, um zu versuchen zu tun, eine Auflösung...Kommt der Lebensdauer Anwendungsbereich vom
RequestLifetimeScopeProvider
...Es hat zu arbeiten, um Unterstützung tools wie Einblick , dynamisch-Packung/proxy die dependency resolver -, um-instrument. Das ist, warum Sie nicht nur gegossen
DependencyResolver.Current as AutofacDependencyResolver
.Ziemlich alles, was mit der
Autofac.Integration.Mvc.AutofacDependencyResolver
erfordertHttpContext
.Das ist, warum Sie immer dieser Fehler. Es spielt keine Rolle, wenn Sie keine Abhängigkeiten haben, sind registriert
InstancePerHttpRequest
-AutofacDependencyResolver
wird immer noch ein web-Kontext.Ich vermute, dass die anderen workflow-app, die Sie hatte, wo dies kein Problem war eine MVC-app oder etwas, wo es war immer eine web-Kontext.
Hier ist, was ich empfehlen würde:
Autofac.Integration.WebApi.AutofacWebApiDependencyResolver
.AutofacHostFactory.Container
und das host-factory-Implementierung, um Abhängigkeiten aufzulösen. (WCF ist ein wenig seltsam mit seinen singleton-host-Potenzial, etc.. also "pro Antrag" ist nicht ganz so einfach.)CommonServiceLocator
Umsetzung für Autofac. Es nicht schaffen, Wunsch Leben, aber es kann einige Probleme lösen.Wenn Sie halten diese Dinge direkt und nicht versuchen, die verschiedenen Resolver außerhalb Ihrer heimischen Lebensräume, wie Sie waren, dann sollten Sie nicht laufen in Probleme.
Sie kann ziemlich sicher verwenden
InstancePerApiRequest
undInstancePerHttpRequest
Synonym service-Registrierungen. Diese beiden Erweiterungen verwenden Sie die gleiche Lebensdauer Anwendungsbereich tag-so die Vorstellung von einer MVC-web-Anfrage und eine web-API Anfrage können ähnlich behandelt werden, auch wenn die zugrundeliegende Lebensdauer-scope-in einem Fall basiert aufHttpContext
und die andere basiert aufIDependencyScope
. So könnte man theoretisch teilen, eine Anmeldung Modul über apps/app-Typen und es sollte das richtige zu tun., Wenn Sie die ursprünglichen Autofac-container-speichern Sie Ihre eigenen Referenz. Anstatt davon auszugehen Autofac zurück, die container irgendwie müssen Sie möglicherweise speichern Sie einen Verweis auf Ihre Bewerbung-container wenn Sie brauchen, um es später, aus welchem Grund auch immer.
Sparen Sie eine Menge Probleme die Straße hinunter.
Leider es funktioniert nicht 🙁 : No-Bereich mit einem Tag-matching 'AutofacWebRequest' ist sichtbar aus dem Rahmen, in dem die Instanz beantragt wurde. Dies weist im Allgemeinen darauf hin, dass eine Komponente registriert als pro-HTTP-request angefordert wird, durch eine SingleInstance() Komponente (oder einem ähnlichen Szenario.) Unter der web-integration immer Anfrage Abhängigkeiten aus dem DependencyResolver.Aktuelle oder ILifetimeScopeProvider.RequestLifetime, nie aus dem container selbst.
Warten Sie, ich habe es! Funktioniert, wenn ich mich anmelden alles wie InstancePerLifetimeScope(). Gute Sachen, Dank
Ist das wirklich eine gültige Antwort. Ursache, die ich hier mache, ` ` var Typ = Typ.GetType(id); return AutofacDependencyResolver.Aktuelle.GetService(type); `` Aber bekomme immer noch die fehlende HttpContext Ausnahme. Und ich sehe auch den Grund in der Autofac. Code : github.com/autofac/Autofac.Mvc/blob/develop/src/... Also, wie kann ich gehen, um dieses.
ja, es ist eine gültige Antwort. Möglicherweise müssen Sie die post eine neue Frage. Fehlt HttpContext werden konnte, weil die Sie aufrufen
GetService
wenn es keinen Kontext, nicht wegenAutofacDependencyResolver.Current
. Lesen Sie diese FAQ und wenn du dann immer noch Probleme haben, stellen Sie eine neue Frage mit deinem code.InformationsquelleAutor Travis Illig
Meine Annahmen:
IUserRepo
ist abhängig von HttpContextWenn meine Annahme richtig, Workflow-Projekt hätte keine Ahnung von
HttpContext.Current
.WindowsWorkflow Projekt läuft die ganze Zeit (Wenn ich es richtig verstehe - eigentlich nicht die Arbeit mit dieser Technologie). Wo, wie MVC basiert auf HTTP-requests.
HttpContext.Current
wird erst aufgefüllt, wenn es zu einem Antrag kommen. Wenn keine Anfrage - diese variable null ist. Was passiert, wenn es keine Anfrage, aber der Workflow-Instanz zugreifen möchtenHttpContext
? Richtig - null-Verweis-Ausnahme. Oder in deinem Fall der Auflösung von Abhängigkeiten Ausnahme.Was Sie tun müssen:
User.Current
oderHttpContext.Current
. Workflow-Modul (falls erforderlich) mit allen Workflow-spezifische Implementierungen.IUserRepo
erstellen-Implementierung, die ist nicht abhängig von HttpContext. Dies wird wahrscheinlich am problematischsten sein zu tun.Habe ich etwas ähnliches gemacht für Quartz.Net Ausführung in Azure. Siehe mein blog post dazu: http://tech.trailmax.info/2013/07/quartz-net-in-azure-with-autofac-smoothness/. Dieser Beitrag wird dir nicht helfen, direkt, aber erklärt, dass meine Argumentation für die Spaltung autofac-Module.
Update als pro-Kommentar: WebApi klärt eine Menge Dinge hier. WebApi Anfrage gehen Sie nicht durch die selbe pipeline wie MVC Anfragen. Und WebApi Controller keinen Zugriff auf HttpContext. Sehen diese Antwort.
Nun, je nachdem, was Sie tun, in Ihrem wepApi controller, die Sie ändern möchten, die
IUserRepo
Umsetzung in der Lage sein, um die Arbeit mit MVC und WebApi.WebApi klärt die Dinge. Siehe mein update in der post.
Vielen Dank für immer zurück. Das macht Sinn, jetzt mit Web-Api keine HttpContext aber was würden Sie vorschlagen, ich mache mit, aktualisiert wissen? Der workflow nicht wirklich BRAUCHEN, eine HttpContext, spielt es keine Referenz es überall, es muss nur zur Behebung des IUserRepo Abhängigkeit wie jede andere also ich bin mir immer noch nicht sicher, warum es ist, sich zu beschweren. Warum brauche ich eine HttpContext-zum auflösen der Abhängigkeit? Warum kann ich nicht einfach beheben ohne. Sicher, es werde in einem anderen Bereich, aber ich habe schon angenommen, dass die Einschränkung durch die Verwendung DependencyResolver, es ist ein Grenzfall, ich bin ok mit, da ich nicht einmal rufen uow.Commit()
Weder UserRepository noch eine Ihrer Abhängigkeiten eine Abhängigkeit HttpContext
Nun, das ist eine ausgezeichnete Frage! können Sie nach Ihrem Registrierungs-code ?
InformationsquelleAutor trailmax
Wir sind derzeit in einer situation, wo wir haben tests, die leiden unter der "fehlende httpcontext' Frage aber noch nicht die ausgezeichnete Empfehlungen vor, da die version-Einschränkungen.
Die Art, wie wir es gelöst wurde, um zu erstellen ein 'mock' http-Kontext in unserem test-setup:
siehe: Mock HttpContext.Aktuell im Test Init-Methode
InformationsquelleAutor SteveT