2010-04-19 15 views
5

Nuovo al castello/Windsor, per favore abbiate pazienza.castello PerRequestLifestyle non riconosciuto

Attualmente sto usando il quadro System.Web.Mvc.Extensibility e nel suo codice di start up, ha registrato HttpContextBase simile al seguente:

container.Register(Component.For<HttpContextBase>().LifeStyle.Transient.UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current))); 

Quello che ho voluto fare è modificare il comportamento e cambiare lo stile di vita di httpContextBase essere PerWebRequest.

quindi devo modificare il codice al seguente:

container.Register(Component.For<HttpContextBase>().LifeStyle.PerWebRequest.UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current))); 

Tuttavia, quando faccio questo, ho ottenuto il seguente errore:

System.Configuration.ConfigurationErrorsException: Looks like you forgot to 
register the http module Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule 
Add '<add name="PerRequestLifestyle" 
type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.MicroKernel" 
/>' to the <httpModules> section on your web.config 

che ho fatto sotto <system.web> e <system.webServer>, comunque , Sto ancora ricevendo lo stesso errore. Qualche suggerimento?

Grazie in anticipo.

Aggiornamento

aggiunto blocco di codice per richiesta

Nel quadro system.web.mvc.extensibility, v'è una classe chiamata extendedMvcApplication che eredita da HttpApplication, e nel metodo Application Start, si chiama BootStrapper.Execute(). Questa implementazione di questo metodo è il seguente:

public void Execute() 
    { 
     bool shouldSkip = false; 

     foreach (IBootstrapperTask task in ServiceLocator.GetAllInstances<IBootstrapperTask>().OrderBy(task => task.Order)) 
     { 
      if (shouldSkip) 
      { 
       shouldSkip = false; 
       continue; 
      } 

      TaskContinuation continuation = task.Execute(ServiceLocator); 

      if (continuation == TaskContinuation.Break) 
      { 
       break; 
      } 

      shouldSkip = continuation == TaskContinuation.Skip; 
     } 
    } 

Come si può vedere, si scorre l'elenco dei IBootStrapperTask e cerca di eseguirli. E 'il caso che ho un compito che si registrano i percorsi nella mia app MVC:

public class RegisterRoutes : RegisterRoutesBase 
{ 
    private HttpContextBase contextBase; 

    protected override TaskContinuation ExecuteCore(IServiceLocator serviceLocator) 
    { 
     contextBase = serviceLocator.GetInstance<HttpContextBase>(); 
     return base.ExecuteCore(serviceLocator); 
    } 

    protected override void Register(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
     routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" }); 
     routes.IgnoreRoute("{*robotstxt}", new { robotstxt = @"(.*/)?robots.txt(/.*)?" }); 

     XmlRouting.SetAppRoutes(routes, contextBase.Server.MapPath("~/Configuration/Routes.xml")); 
    } 
} 

si può vedere che ho bisogno di getInstance (risolvere) un oggetto httpcontextbase tale che posso ottenere il percorso del server di un file XML .

+1

quando si risolve quell'oggetto? a che punto? –

+0

su Application_Start(), è troppo presto? – Herman

+0

@Herman: al momento non è supportato. Cosa stai cercando di risolvere in Application_Start()? –

risposta

7

partire da questa scrittura, lo stile di vita PerWebRequest non supporta la risoluzione a Application_Start().

Vedere descrizione del problema e discussione:

Soluzioni alternative per questo caso particolare:

  1. Registrati RegisterRoutes come istanza, passando esplicitamente la cu contesto attuale come parametro costruttore, ad es.:

    container.Register(Component.For<IBootstrapperTask>() 
              .Instance(new RegisterRoutes(Context))); 
    
  2. Uso HostingEnvironment.MapPath invece di contextBase.Server.MapPath. Vuoi renderlo mockable? Usalo attraverso una semplice interfaccia, ad es .:

    interface IServerMapPath { 
        string MapPath(string virtualPath); 
    } 
    
    class ServerMapPath: IServerMapPath { 
        public string MapPath(string virtualPath) { 
         return HostingEnvironment.MapPath(virtualPath); 
        } 
    } 
    
    container.AddComponent<IServerMapPath, ServerMapPath>(); 
    

poi iniettare IServerMapPath nella vostra RegisterRoutes.

+0

grazie per l'aggiornamento, sarà sicuramente dare un'occhiata. – Herman