2012-04-05 10 views
14

Zarejestrowałem komponent jak to w moim Global.asax.cs:Jak rozwiązać Autofac InstancePerHttpRequest

ContainerBuilder builder = new ContainerBuilder(); 
builder.RegisterControllers(Assembly.GetExecutingAssembly()); 

builder.RegisterType<WebWorkContext>().As<IWorkContext>().InstancePerHttpRequest(); 

IContainer container = builder.Build(); 
DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

// This is where my error happens, not sure why? 
var workContext = container.Resolve<IWorkContext>(); 

WebWorkContext klasa:

public class WebWorkContext : IWorkContext 
{ 
    // Left out other code 
} 

IWorkContext interfejs:

public interface IWorkContext 
{ 
    // Left out other code 
} 

Błąd, który otrzymuję to:

Brak zakresu z dopasowaniem znacznika "httpRequest" jest widoczny z zakresu, w którym wystąpiono o wystąpienie. Zasadniczo oznacza to, że komponent zarejestrowany jako żądanie na HTTP jest ponownie sprawdzany przez komponent SingleInstance() (lub podobny scenariusz). W ramach integracji sieciowej zawsze żądaj zależności od DependencyResolver.Current lub ILifetimeScopeProvider.RequestLifetime, nigdy z samego kontenera .

Jak to działa? Z tego powodu chcę tego w ten sposób, ponieważ kontekst pracy obsługuje takie rzeczy jak pozyskanie obecnego klienta itp.

Jeszcze więcej pytań. Czy rozsądne/najlepsze praktyki są rejestrowane od razu? Czy będą scenariusze, które będę potrzebował dodać więcej komponentów na innym etapie?

+0

Jeżeli starasz się zrobić swoją rozdzielczość? – cecilphillip

+0

Po prostu bawię się, więc zrobiono to bezpośrednio po zbudowaniu kontenera w metodzie uruchamiania aplikacji. Nie wiem, jak zdobyć kontener w mojej aplikacji? –

Odpowiedz

22

Rejestracji oznaczonych InstancePerHttpRequest oczekuje się, że zostaną rozstrzygnięte z konkretnego zagnieżdżonego zakresu życia, który jest tworzony i usuwany podczas każdego żądania HTTP.

Jeśli dodasz IWorkContext jako parametr konstruktora do jednego ze swoich kontrolerów, zobaczysz, że instancja została wstrzyknięta. W kodzie próbujesz rozwiązać usługę z zakresu czasu życia roota, a nie zagnieżdżonego zakresu życia "na żądanie".

Jeśli chcesz przetestować rozwiązywanie usługi bez uruchamiania aplikacji, musisz utworzyć zasięg dożywotni z tym samym znacznikiem, który został utworzony podczas żądania HTTP. W integracji MVC 3 zasięg życia jest oznaczany jako "httpRequest".

using (var httpRequestScope = container.BeginLifetimeScope("httpRequest")) 
{ 
    Assert.That(httpRequestScope.Resolve<IWorkContext>(), Is.Not.Null); 
} 

myślę, że będę aktualizować integrację MVC wystawiać „HttpRequest” nazwę znacznika publicznie za pośrednictwem interfejsu API tak, że ciąg wartości nie muszą być trudne kodowane. Możliwe jest również przekazanie własnej implementacji ILifetimeScopeProvider do AutofacDependencyResolver, aby można było kontrolować tworzenie zasięgów czasu życia poza środowiskiem wykonawczym ASP.NET. Jest to przydatne w testach jednostkowych, gdy nie ma dostępnego żądania HTTP.

+2

Tak, proszę uczynić HttpRequestTag w RequestLifetimeScopeProvider publiczne. Wtedy nie musimy sztywno kodować wartości tagu. –

1

Robię to w WebForms:

this.RoutingService = ((Global)HttpContext.Current.ApplicationInstance).ContainerProvider.RequestLifetime.Resolve<RoutingService>(); 
Powiązane problemy