Ich möchte Registrierungen in einem Unity-Container konfigurieren, der von ASP.NET Web API 2 basierend auf Eigenschaften einer HTTP-Anfrage verwendet wird. Eine Anforderung an /api/database1/values
sollte beispielsweise zu einer Unity-Containerkonfiguration mit einer für Datenbank1 konfigurierten IDbContext
führen, während eine Anforderung an /api/database4/values
eine für Datenbank4 konfigurierte IDbContext
erhält.Unity-Container pro Anfrage in OWIN-Middleware konfigurieren
Ich habe so weit mit der Verwendung UnityHierarchicalDependencyResolver
als Abhängigkeits-Resolver, so registriert Typen mit HierarchicalLifetimeManager
letzten nur für die Lebensdauer der Anfrage. Dies funktioniert gut für die Typen gelöst pro Anfrage. Aber wie man sie registriert pro Anfrage mit OWIN Middleware ist über mich hinaus.
In meiner Middleware, wird ein Aufruf an System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUnityContainer))
eine Instanz von IUnityContainer
, aber es ist die gleichen Container für alle Anfragen aus früheren Anfragen aller Registrierungen inklusive.
Durch die Kapselung UnityHierarchicalDependencyResolver
mit meiner eigenen Implementierung von IDependencyResolver
kann ich sehen, dass IDependencyResolver.BeginScope
nicht viel später im Prozess aufgerufen wird. Daher scheint das Problem so zu sein, dass der untergeordnete Container nicht erstellt wird, bis die Web-API aufwacht, lange nachdem meine Middleware Next(..)
aufgerufen hat.
Gibt es eine Möglichkeit, den Umfang meines Dependency Resolvers früher zu starten? Gibt es eine andere Strategie, die ich vermisse? Für den Fall, dass es einen Unterschied macht, hosste ich in IIS, bevorzuge aber den OWIN-Middleware-Ansatz.
aktualisiert
Dies ist keine Antwort, und es ist zu groß für einen Kommentar, aber nach kämpfen, diese zu lösen mit Unity entschied ich mich zu Autofac wechseln und es fiel einfach an seinen Platz.
Die Autofac OWIN Pakete (Autofac.Mvc5.Owin
, Autofac.Owin
, Autofac.WebApi2.Owin
) machen es einfach tot Autofac innerhalb der OWIN Pipeline zu verwenden und entsprechende Lebensdauerverwaltung in ASP.NET MVC und Web API zu gewährleisten. Dies war das fehlende Glied.
Ich konnte keine Möglichkeit finden, den Container pro Anfrage neu zu konfigurieren, aber es war zumindest möglich, eine Fabrik pro Anfrage zu konfigurieren (also ja, @Haukinger und @alltej, du warst richtig, da reinzukommen) ., dass Richtung
So melde ich eine Fabrik wie:
builder.RegisterType<DataDependencyFactory>().InstancePerRequest();
Und die Methode der das Werk schaffen registrieren wie:
builder
.Register(c => c.Resolve<DataDependencyFactory>().CreateDataDependency())
.As<IDataDependency>()
.InstancePerRequest();
die Fabrik Registrierung dieses Weg ist besonders nützlich, weil stromabwärts Abhängige nicht auf die Fabrik achten müssen. Ich mag das, weil meine Angehörigen keine Fabrik brauchen, sie brauchen eine Instanz. Der Container biegt sich auf die Bedürfnisse meiner Angehörigen, nicht andersherum :)
Dann, in einem Stück OWIN Middleware, ich die Fabrik auflösen, und legen Sie eine Eigenschaft auf sie nach den Eigenschaften der Anfrage. Bei einer nachfolgenden Auflösung von IDataDependency
in einem MVC- oder Web-API-Controller oder einem beliebigen späteren Element in der OWIN-Pipeline wird eine Instanz entsprechend der Eigenschaft in der Factory konfiguriert.
FWIW, ich fühle mich bestätigt, dass ich nicht versuche, etwas wirklich lächerliches zu tun, da die Autofac-Dokumentation das Konzept validiert. http://docs.autofac.org/en/latest/faq/per-request-scope.html#implementing-custom-per-request-semantics _ ** Sie können einen benutzerdefinierten Mechanismus implementieren, der die Möglichkeit zur Registrierung und Lösung bietet Abhängigkeiten auf Anfragebasis ** _. Obwohl ich es vorziehen würde, bei Unity zu bleiben, würde ich, wenn das ein harter Kampf ist, einen alternativen IoC-Container wie Autofac in Erwägung ziehen. – Snixtor
Betrachten Sie eine Factory für Ihren 'IDBContext', die den Kontext erstellt und die relevanten Anforderungseigenschaften als Parameter erhält? Auf diese Weise benötigen Sie nur eine Registrierung für die Fabrik. – Haukinger
Eine Fabrik benötigt immer noch eine Konfiguration pro Anfrage. Das bedeutet, dass die Verbindung direkt (nicht ideal) erkannt werden muss oder dass eine Art Verbindungskontext über den IoC-Container eingegeben werden muss, was mich nur auf den ersten Platz bringt. Oder gibt es etwas, das ich vermisse? – Snixtor