2012-04-05 21 views
14

Ho registrato un componente come questa nel mio Global.asax.cs:Come risolvere 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 classe:

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

IWorkContext interfaccia:

public interface IWorkContext 
{ 
    // Left out other code 
} 

L'errore che sto ottenendo è:

Nessun ambito con un tag corrispondente a "httpRequest" è visibile dall'ambito in cui è stata richiesta l'istanza. Questo in genere indica che un componente registrato come richiesta per HTTP viene rivendicato da un componente SingleInstance() o uno scenario simile. Nell'integrazione Web vengono sempre richieste dipendenze da DependencyResolver.Current o ILifetimeScopeProvider.RequestLifetime, mai dal contenitore stesso .

Come posso farlo funzionare? Questo perché lo voglio in questo modo è perché il contesto di lavoro gestisce cose come ottenere il cliente attuale ecc.

Altre domande. È saggio/le migliori pratiche registrarsi tutti in una volta? Saranno gli scenari che avrò bisogno di aggiungere più componenti in un altro stadio?

+0

Dove stai cercando di fare la vostra risoluzione? – cecilphillip

+0

Mi sto solo divertendo, quindi questo è stato fatto direttamente dopo che il contenitore è stato creato nel metodo di avvio dell'applicazione. Non so come ottenere il contenitore altrove nella mia app? –

risposta

22

registrazioni che sono contrassegnati con InstancePerHttpRequest dovrebbero essere risolti da una determinata portata vita nidificata creato e disposto durante ciascuna richiesta HTTP.

Se si aggiunge IWorkContext come parametro del costruttore a uno dei controller, si scoprirà che un'istanza è stata iniettata. Nel codice si sta tentando di risolvere il servizio dall'ambito della durata di root e non dall'ambito di validità "per richiesta" annidato.

Se si desidera testare la risoluzione del servizio senza eseguire l'applicazione, sarà necessario creare un ambito di durata con lo stesso tag di quello creato durante la richiesta HTTP. Nell'integrazione MVC 3 l'ambito di vita è contrassegnato come "httpRequest".

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

penso di aggiornare l'integrazione MVC per esporre il "httpRequest" nome del tag pubblicamente tramite l'API in modo che i valori di stringa non hanno bisogno di essere codificato duro. È anche possibile passare la propria implementazione ILifetimeScopeProvider allo AutofacDependencyResolver in modo da poter controllare la creazione di ambiti di durata al di fuori del runtime ASP.NET. Questo è utile nei test unitari quando non è disponibile alcuna richiesta HTTP.

+2

Sì, si prega di rendere HttpRequestTag nel pubblico RequestLifetimeScopeProvider. Quindi non abbiamo bisogno di codificare il valore del tag. –

1

sto facendo questo in WebForms:

this.RoutingService = ((Global)HttpContext.Current.ApplicationInstance).ContainerProvider.RequestLifetime.Resolve<RoutingService>(); 
Problemi correlati